React - 类组件 setState 的 2 种写法、LazyLoad、useState

一、类组件 setState 的 2 种写法

1、对象式 setState
js 复制代码
setState(stateChange, [callback])
  1. stateChange 为状态改变对象,该对象可以体现出状态的更改

  2. callback 是可选的回调函数,它在状态更新完毕、界面也更新后(render 函数调用后)才被调用

js 复制代码
this.setState({
    count: this.state.count + 1,
});
js 复制代码
this.setState(
    {
        count: this.state.count + 1,
    },
    () => {
        console.log("更新后的 count:", this.state.count);
    },
);
2、函数式 setState
js 复制代码
setState(updater, [callback])
  1. updater 为返回 stateChange 对象的函数,updater 可以接收到 prevState 和 props 参数

  2. callback 是可选的回调函数,它在状态更新完毕、界面也更新后(render 函数调用后)才被调用

js 复制代码
this.setState((prevState, props) => ({
    count: prevState.count + 1,
}));
js 复制代码
this.setState(
    (prevState, props) => ({
        count: prevState.count + 1,
    }),
    () => {
        console.log("更新后的 count:", this.state.count);
    },
);
3、注意事项
  1. 如果新状态不依赖于原状态,使用对象式 setState;如果新状态依赖于原状态,使用函数式 setState
jsx 复制代码
// 最终 count 为 1,两次都基于旧的 this.state.count 计算

import { Component } from "react";

export default class App extends Component {
    state = {
        count: 0,
    };

    add = () => {
        this.setState({
            count: this.state.count + 1,
        });
        this.setState({
            count: this.state.count + 1,
        });
    };

    render() {
        return (
            <div>
                <h3>{this.state.count}</h3>
                <button onClick={this.add}>Add</button>
            </div>
        );
    }
}
jsx 复制代码
// 最终 count 为 2,每次都基于上次的 this.state.count 计算

import { Component } from "react";

export default class App extends Component {
    state = {
        count: 0,
    };

    add = () => {
        this.setState((prevState, props) => ({
            count: prevState.count + 1,
        }));
        this.setState((prevState, props) => ({
            count: prevState.count + 1,
        }));
    };

    render() {
        return (
            <div>
                <h3>{this.state.count}</h3>
                <button onClick={this.add}>Add</button>
            </div>
        );
    }
}
  1. 如果需要在 setState 执行后获取最新的状态数据, 要在 callback 中读取
jsx 复制代码
this.setState({
    count: this.state.count + 1,
});
console.log(this.state.count);

// 输出结果为 0
jsx 复制代码
add = () => {
    this.setState((prevState, props) => ({
        count: prevState.count + 1,
    }));
    console.log(this.state.count);

    // 输出结果为 0
};

二、LazyLoad

1、基本介绍
  1. 通过 lazy 函数配合 import 函数动态加载路由组件,路由组件代码会被分开打包

  2. 通过 <Suspense> 指定,在加载得到路由打包文件前,显示一个自定义加载界面

2、演示
(1)page
  1. About 页面
jsx 复制代码
import { Component } from "react";

export default class About extends Component {
    render() {
        return <h2>About</h2>;
    }
}
  1. Home 页面
jsx 复制代码
import { Component } from "react";

export default class Home extends Component {
    render() {
        return <h2>Home</h2>;
    }
}
  1. Loading 页面
jsx 复制代码
import { Component } from "react";

export default class Loading extends Component {
    render() {
        return (
            <div>
                <h1 style={{ backgroundColor: "gray", color: "orange" }}>Loading...</h1>
            </div>
        );
    }
}
(2)main
  1. App 组件
jsx 复制代码
import { Component, lazy, Suspense } from "react";
import { NavLink, Route } from "react-router-dom";
import Loading from "./pages/Loading";
import "./App.css";

const Home = lazy(() => import("./pages/Home"));
const About = lazy(() => import("./pages/About"));

export default class App extends Component {
    render() {
        return (
            <div>
                <div>
                    <NavLink to="/about">About</NavLink>
                    <NavLink to="/home">Home</NavLink>
                </div>
                <div>
                    <Suspense fallback={<Loading />}>
                        <Route path="/about" component={About} />
                        <Route path="/home" component={Home} />
                    </Suspense>
                </div>
            </div>
        );
    }
}
css 复制代码
.active {
    color: red;
}
  1. index.js
js 复制代码
import ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";
import App from "./App";

ReactDOM.render(
    <BrowserRouter>
        <App />
    </BrowserRouter>,
    document.getElementById("root"),
);
3、打包影响
  1. 使用 LazyLoad 后的打包
  1. 不使用 LazyLoad 后的打包

三、useState

1、基本介绍
  • useState 让函数式组件也可以有 state,并进行 state 数据的读写操作
js 复制代码
const [xxx, setXxx] = useState(initValue)
  1. initValue:第一次初始化指定的值在内部作缓存

  2. [xxx, setXxx]:包含 2 个元素的数组,第 1 个为内部当前状态值,第 2 个为更新状态值的函数

  • setXxx 的 2 种写法
  1. setXxx(newValue):参数为非函数值,直接指定新的状态值,内部用其覆盖原来的状态值

  2. setXxx(value => newValue):参数为函数,接收原本的状态值,返回新的状态值,内部用其覆盖原来的状态值

2、基本使用
jsx 复制代码
import { useState } from "react";

export default function App() {
    const [count, setCount] = useState(0);

    const add = () => {
        setCount(count + 1);
    };

    return (
        <div>
            <h3>{count}</h3>
            <button onClick={add}>Add</button>
        </div>
    );
}
3、注意事项
  • 如果新状态不依赖于原状态,setXxx 使用参数为非函数值;如果新状态依赖于原状态,setXxx 使用参数为函数
jsx 复制代码
// 最终 count 为 1,两次都基于旧的 count 计算

import { useState } from "react";

export default function App() {
    const [count, setCount] = useState(0);

    const add = () => {
        setCount(count + 1);
        setCount(count + 1);
    };

    return (
        <div>
            <h3>{count}</h3>
            <button onClick={add}>Add</button>
        </div>
    );
}
jsx 复制代码
// 最终 count 为 2,每次都基于上次的 count 计算

import { useState } from "react";

export default function App() {
    const [count, setCount] = useState(0);

    const add = () => {
        setCount((prevCount) => prevCount + 1);
        setCount((prevCount) => prevCount + 1);
    };

    return (
        <div>
            <h3>{count}</h3>
            <button onClick={add}>Add</button>
        </div>
    );
}
相关推荐
世界哪有真情1 小时前
拿人类意识卡 AI?等于用 bug 验收正式产品
前端·人工智能·后端
鱼樱前端1 小时前
别再自己拼凑了!这款 Vue 3.5+ 严肃产品级组件库,把 AI 对话、工作流和复杂数据全包了!
javascript·vue.js·github
Listen·Rain2 小时前
Vue3:setup详解
前端·javascript·vue.js
Patrick_Wilson2 小时前
修好 bug 只是开始:一次由监控需求反向重构日志结构的复盘
前端·监控·数据可视化
kyriewen3 小时前
面试官让我优化一个卡死的表格,我打开 Claude 五秒重写,他放下咖啡问我要不要来当组长
前端·javascript·面试
‘’林花谢了春红‘’3 小时前
小玩意 生日快乐
css·html·css3
小粉粉hhh3 小时前
React(二)——dom、组件间通信、useEffect
前端·javascript·react.js
Csvn4 小时前
🤖 AI 生成前端代码的 5 个典型翻车现场及修复指南
前端
IT_陈寒4 小时前
SpringBoot自动装配坑了我一天,原来问题出在这
前端·人工智能·后端
索西引擎5 小时前
【React】key 属性:协调算法中的元素标识机制与最佳实践
前端·javascript·react.js