调用setState 之后发生了什么?

触发状态更新

当你在组件里调用:
this.setState({ count: this.state.count + 1 });

React 并不会马上修改 this.state,而是 把更新请求放到一个队列中(即所谓的异步/批量更新机制)。

合并新旧状态

  • React 会将你传入的对象 { count: newValue } 和现有的 state 合并(shallow merge,浅合并)。

  • 如果传入的是函数 setState((prevState, props) => {...}),React 会先执行这个函数,得到新的部分 state,再合并。

标记组件需要更新

  • React 在内部给该组件打上一个 “需要重新渲染” 的标记。

  • 但此时不会立即更新 UI,而是交给 调度器(Scheduler) 统一管理,可能会延迟批处理(提高性能)。

调用 Reconciliation(协调算法)

  • React 会触发 虚拟 DOM 的 diff 过程,比较更新前后的 Virtual DOM 树。

  • 找出需要真正修改的部分(例如某个 <span> 的文字变了,而不是整个组件都重建)。

渲染更新(Commit 阶段)

  • React 把差异(DOM diff 结果)应用到真实 DOM 上。

  • 更新 UI,同时调用相关生命周期方法 / hooks:

  1. 类组件:componentDidUpdate

  2. 函数组件:useEffect(在 commit 后执行)

触发副作用

  • 例如 useEffect 的回调函数执行。

  • 如果有 setState 在这些副作用里,会再次触发更新,进入新的更新循环。

流程总结

调用 setState()
   ↓
将更新加入队列(可能批处理)
   ↓
合并 state
   ↓
标记组件需要更新
   ↓
虚拟 DOM diff
   ↓
最小化更新真实 DOM
   ↓
调用生命周期 / hooks

小知识点

  • setState 是 异步的(React 会合并多次调用以优化性能)。

  • 如果你需要拿到更新后的 state,可以用:

this.setState((prev) => ({ count: prev.count + 1 }), () => {
  console.log(this.state.count); // 回调里能拿到最新值
});
  • React 18 以后,在事件回调里,setState 默认是批量的。
posted @ 2025-09-29 16:06  煜火  阅读(14)  评论(0)    收藏  举报