react坑点记录

张开发
2026/4/9 16:54:55 15 分钟阅读

分享文章

react坑点记录
this.setState({num:2})setTimeout((){this.setState({num:4})},2000)延迟 2 秒后把组件状态里的 num 更新成 4。setTimeout(…, 2000)等待 2000ms2 秒 后执行里面的函数this.setState({ num:4 })React 组件更新状态方法把 num 设为 4① 异步执行setTimeout 是异步任务不会阻塞代码2 秒后才会进入任务队列执行。② React 状态更新是异步的setState 本身也是异步更新不会立刻修改 state。③ this 指向问题高频坑点在 setTimeout 回调里用 this必须确保 this 指向当前组件实例。用箭头函数没问题继承外层 this用普通 function 会丢 this报错this.setState({num:2})this.setState({num:4})最终 num 只会是 3不会先变成 2 再变成 3页面只会渲染一次 3。这是 React setState 批量更新机制导致的连续调用 setState 会被合并在同步代码、合成事件、生命周期里React 不会每次 setState 都立即更新而是先把多个更新合并成一次最后一起执行。后面的会覆盖前面的this.setState({ num: 2 })this.setState({ num: 3 })这两句是连续同步执行React 会把它们合并先记录要更新 num:2又记录要更新 num:3最终只执行最后一次num3页面只会渲染一次值是 3不会出现 2 → 3 的过程。// 初始 this.state.num 0this.setState({num:this.state.num1})// 第1次console.log(this.state.num)// 日志1this.setState({num:this.state.num1})// 第2次console.log(this.state.num)// 日志2setTimeout((){this.setState({num:this.state.num1})// 第3次console.log(this.state.num)// 日志3this.setState({num:this.state.num1})// 第4次console.log(this.state.num)// 日志4},0)控制台输出顺序0023最终 state.num 3前两次 setState同步批量更新jsthis.setState({ num: this.state.num 1 })this.setState({ num: this.state.num 1 })关键点setState 是异步的同步代码里连续 setState 会被合并合并时后面的会覆盖前面的this.state 不会立即更新所以两次 setState 拿到的都是 原始值 001、01 → 最终合并成 num 1所以前两个 console.log 输出plaintext00setTimeout 里的 setState重点jssetTimeout(() {// 此时批量更新已结束state 已经是 1this.setState({ num: this.state.num 1 }) // 112console.log(this.state.num) // 2this.setState({ num: this.state.num 1 }) // 213console.log(this.state.num) // 3}, 0)关键点setTimeout 里脱离 React 批量更新setState 会同步更新 state每次 setState 后 this.state 立即生效所以第一次1 → 2第二次2 → 3输出plaintext23同步代码里 setState 是异步批量更新不会立即修改 state连续调用会被合并后面覆盖前面。setTimeout 属于宏任务会在同步代码执行完才运行。定时器里的 setState 脱离 React 批量更新变成同步执行每次调用都会立即更新 state后面能拿到前面的值。所以同步里两次 1 最终只变成 1定时器里两次 1 会变成 2、3。

更多文章