Skip to content

setState 是同步的吗? ​

setState 安排一次更新,不保证在下一行就能读到新状态。React 18 在事件处理、Promise、定时器里都会把同一轮里的多次更新合并。要基于旧状态计算,传入函数。

原理 ​

类组件的 setState(partial) 是浅合并。函数组件的 useState 替换整个状态,对象要自己展开。两者都支持函数形式,参数是这一次更新队列里的上一个状态。

jsx
setCount((count) => count + 1)

同一事件里写两次 setCount(count + 1),如果 count 来自这次渲染的闭包,两次都是同一个数加一。函数形式才会累加。

更新被标上优先级。输入用紧急更新,大列表可以用 startTransition 标成可打断。见 React Fiber。

类组件的 setState 第二个参数是更新提交后的回调。函数组件里对应的是 useEffect,它在绘制之后。

追问 ​

什么时候看起来像同步?

在 React 控制的事件里,处理函数跑完才会重新渲染,所以下一行读 this.state 仍是旧的。不要用「异步函数」来描述它。它是调度,不是返回 Promise 的 API。useState 的 setter 也不要 await。

对象状态会被深合并吗?

不会。类组件只合并第一层。嵌套字段要先拷贝再改。函数组件连第一层也不会替你合并。

易错点 ​

  • 连续非函数形式的更新互相覆盖。
  • 在 render 里调用 setState。条件不严就会死循环。
  • 把 props 复制进 state 后,父组件更新了,子组件的 state 还是旧的。能从 props 算出来的值不要再存一份。

相关 ​