You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React 17中setState回调为何仅第一个同步执行?

为什么React 17中setState的函数式更新回调看起来是同步执行的?

首先要明确核心区别:你传给setTest的函数式更新回调((e) => {...})本身是同步执行的,React所说的“setState是异步”,指的是state的最终更新和组件重新渲染是异步批量处理的,而非这个回调函数的执行时机。

你的代码执行顺序拆解

当点击按钮触发onClick回调时,代码会按以下顺序执行:

  1. 第一个setTest调用:React立即同步执行传入的函数式回调,输出first 0,返回新state值1。此时React不会立刻更新组件的test变量,而是把这个更新操作加入内部的更新队列。
  2. 执行console.log("inside1"),输出inside1。
  3. 第二个setTest调用:React同样立即同步执行传入的回调,此时回调接收的e是前一个更新返回的1(函数式更新会自动获取队列中最新的state值),输出second 1,返回新state值2,这个更新也被加入队列。
  4. 当onClick回调执行完毕后,React会批量处理队列中的所有更新,将test的值最终设置为2,然后触发组件重新渲染,此时组件顶部的console.log("HEYY STATE", test)会输出HEYY STATE 2。

为什么你觉得只有第一个回调是同步的?

你可能混淆了“函数式更新回调的执行”和“state更新的生效时机”:

  • 所有函数式更新的回调都是同步执行的,第二个回调的执行在inside1之后,完全是因为代码的书写顺序(第二个setTest调用在console.log("inside1")之后),而非异步。
  • React的异步特性体现在:即使你执行了多次setTest,组件的test变量不会立刻更新,直到React完成批量更新并触发重新渲染。

补充说明

在React 17中,合成事件(比如onClick)内的setState会被自动批量处理,这也是为什么两次setTest的更新会合并成一次重新渲染,而不是触发两次渲染。如果是在原生事件或者定时器回调中调用setState,React 17不会进行批量处理,此时每次setState都会触发一次渲染,但函数式更新的回调依然是同步执行的。

内容的提问来源于stack exchange,提问作者Nick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 12:55:25