15、React 调用 setState 后的更新流程

在 React 的 Hooks 里面,通过 useState 可以创建一个 setState 函数。
调用它后,最终会触发页面的更新。
具体更新流程为:

  1. 调用 useState 的 setState 函数:当你调用setState(newState)时,React 将新的状态变更放入一个队列中。
  2. 调度与批处理:更新被延迟处理,并通过内部机制进行批处理(batching),确保多个状态变更可以在一次重渲染中完成,从而减少不必要的更新。
  3. Fiber 结构调度:会经过一系列的调度过程,最终调用scheduleUpdateOnFiber函数来安排 Fiber 树上的工作。
  4. 生成新的 Fiber 结构:从根元素开始遍历,创建一个新的workInProgress Fiber树结构,在这个过程中涉及虚拟 DOM 的生成、使用高效的 DIFF 算法比较新旧状态,并标记需要更新或添加副作用(Side Effects)的 Fiber 节点。
  5. workInProgress Fiber 的创建: 在 beginWork 阶段,会根据新的状态创建 workInProgress Fiber,并在此阶段执行 shouldComponentUpdate 或者 hooks 中的 useEffect、useLayoutEffect 等钩子函数的调度。
  6. Commit 阶段: 最后在 commitWork 阶段,会将 workInProgress Fiber 树上标记为需要更新的部分同步到真实的 DOM 上,并执行副作用,如 DOM 节点插入、删除或属性更改。同时这也是 React 实现其双缓存策略(current Fiber tree 和 workInProgress Fiber tree)切换的地方。
  7. 页面重新渲染:当所有的变更提交完成后,浏览器会根据实际的 DOM 变化重新渲染页面,用户界面得到更新。

1、调用~~setState(obj, [callback])~~函数后,则放到队列中延迟处理,后面批量处理,可以减少不必要的更新
2、一层层的调用到~~scheduleUpdateOnFiber~~函数,用它来调度更新
3、从根元素开始,一层层遍历生成新的 Fiber 结构,其中涉及虚拟 DOM 的生成、DIFF 算法、打上 EffectTag 等等操作(Fiber 是一种包含虚拟 DOM、链表、EffectList 的数据结构)
4、在~~beginWork~~里面生成~~workInProgressFiber~~
5、调用~~completeWork~~创建真实的 DOM
6、最后调用~~commitWork~~实现双缓存的切换
7、最终实现页面的重新渲染


15、React 调用 setState 后的更新流程
https://mrhzq.github.io/职业上一二事/前端面试/每日一题/15、React 调用 setState 后的更新流程/
作者
黄智强
发布于
2024年1月23日
许可协议