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