请从源码实现的角度,详细阐述 React 从触发更新到页面渲染的完整执行流程,包括各个阶段的关键函数调用与内部机制。
考察说明
考查对 React 源码核心执行流程的理解深度,包括调度、协调、提交等关键阶段。
回答思路
- 【回答框架 1】React 的更新流程可划分为调度、协调、提交三个阶段。调度阶段由 Scheduler 负责,通过任务优先级和时间切片机制决定何时执行更新任务,核心入口是 scheduleCallback,对应的源码在 packages/scheduler 中。协调阶段(render 阶段)从根节点开始,通过 beginWork 和 completeWork 递归处理组件,生成新的 Fiber 树,并收集副作用到 effectList,该阶段可中断,入口函数是 renderRoot。提交阶段(commit 阶段)将副作用同步应用到 DOM,依次执行 before mutation、mutation 和 lay
- 【回答框架 2】触发更新的常见方式包括 setState、forceUpdate 和 renderRoot 等,这些操作最终都会进入 scheduleUpdateOnFiber,该方法会标记根节点并调度一次新的渲染。React 使用双缓存机制,在内存中构建 workInProgress 树,完成后直接切换 current 指针,以支持并发特性。
- 【回答框架 3】在协调阶段,React 采用深度优先遍历,beginWork 根据 Fiber 的 tag 类型(如 FunctionComponent、ClassComponent、HostComponent)执行对应的更新逻辑,并生成子节点。completeWork 负责处理 props、ref 和 DOM 属性等,并向上冒泡,收集需要提交的副作用。整个遍历过程通过 workLoop 循环驱动,每次处理一个工作单元,并检查是否超出时间片。
- 【回答框架 4】在提交阶段,commitRoot 首先执行 getSnapshotBeforeUpdate 等生命周期,然后处理 DOM 的增删改,最后执行 useLayoutEffect 和 componentDidMount 等。所有副作用都以 effectList 为基础,按顺序处理,确保 DOM 更新与副作用执行的正确顺序。
- 【回答框架 5】React 18 的并发特性依赖于调度阶段的可中断性,render 阶段如果被更高优先级任务打断,会丢弃已构建的部分 Fiber 树并重新开始,但 commit 阶段必须同步执行以保证一致性。整个流程的设计目标是提升响应性和用户体验。
- 【关键点 1】React 执行流程分为调度、协调(渲染)、提交三阶段。
- 【关键点 2】协调阶段基于 Fiber 树和双缓存机制,可被高优先级任务中断。
- 【关键点 3】提交阶段同步执行 effectList 中的副作用,不可中断。
- 【关键点 4】setState 等更新入口最终都会进入 scheduleUpdateOnFiber。
- 【关键点 5】React 18 的并发渲染依赖调度器的时间切片能力。
- 【易错点 1】容易混淆 render 阶段和 commit 阶段的一一对应关系,实际上 render 可能多次执行而 commit 一次。
- 【易错点 2】不要把开始挂载和更新的流程完全割裂,两者共享同一套渲染机制。
- 【易错点 3】高估并发特性的范围,不是所有更新都能并发,transitions 和默认优先级有差异。