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>
    );
}
相关推荐
一个博客13 小时前
pdf-viewer 实现预览pdf文件
开发语言·javascript·pdf
wuxia211821 小时前
微信小程序单击元素切换元素的显示和隐藏
javascript·微信小程序·setdata
JustHappy21 小时前
古法编程秘籍(二):什么是代码模块化?别背概念,把房间收拾明白就够了
前端·后端
小江的记录本21 小时前
【JVM虚拟机】堆内存分代模型:年轻代(Eden+Survivor)、老年代、元空间Metaspace(附《思维导图》+《面试高频考点清单》)
java·前端·jvm·后端·python·spring·面试
weixin_471383031 天前
图片预解码缓存
前端·浏览器缓存·图片预解码
一起学开源1 天前
一文读懂 ReAct 范式:让 AI Agent 真正学会“思考+行动“
java·javascript·react.js·ecmascript·react·alibaba·智能体开发
郑洁文1 天前
基于网络爬虫的Web敏感信息泄露自动化检测工具
前端·爬虫·网络安全·自动化
游九尘1 天前
JavaScript 实现三段式版本号对比函数(app升级用)
javascript·uni-app
zhiSiBuYu05171 天前
Claude-Code 新手极速上手指南
javascript·node.js
郑洁文1 天前
可视化Web渗透分析工具的设计与实现
前端