前端
漫游 React 源码 - 02 - 渲染流程
React 调用过程
记录 React 调用过程,根据调用的方法名,方便阅读源码实现。
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render( < App / > );
程序启动,首先会调用 ReactDOM.createRoot
方法,创建一个 FiberRoot 对象,表示 React 应用的根节点。之后会调用 render
方法,将 React 应用渲染到 DOM 中。
ReactDOM.createRoot
- 调用
createFiberRoot
, 创建一个 FiberRootNode 对象,这是整个React应用的顶层节点,也可以理解成顶层容器。 - 之后会创建一个 Fiber 对象,HostRoot,作为Fiber 树的跟节点。FiberRootNode 的current会指向 HostRoot。
- 调用RootNode的
render
方法,将 React 应用渲染到 DOM 中。
render
- 调用
updateContainer
方法,将渲染任务添加到更新队列中。 updateContainer
会创建一个 update 对象,并且调用enqueueUpdate
方法,将 update 对象添加到更新队列中。- 调用
scheduleUpdateOnFiber
方法,调度更新任务:标记根节点有待处理的更新,确保根节点被调度。 scheduleUpdateOnFiber
会根据更新的优先级选择同步或异步方式处理:- 同步更新:直接调用
performSyncWorkOnRoot
- 异步更新:将任务交给 Scheduler 调度
- 同步更新:直接调用
performSyncWorkOnRoot
或performConcurrentWorkOnRoot
被调用,开始实际的渲染工作。- 调用
renderRootSync
或renderRootConcurrent
进行渲染工作,这个过程包括: - "递" 阶段:从根节点开始,深度优先遍历整个组件树,为每个组件创建或更新 Fiber 节点。(beginWork
) - "归" 阶段:收集所有副作用(如 DOM 更新),准备提交阶段。(completeWork
) - 渲染完成后,调用
commitRoot
进入提交阶段,将变更应用到实际的 DOM 中。(commitRootWhenReady
) - 提交阶段分为三个子阶段:
- Before mutation:执行 DOM 操作前的准备工作
- Mutation:执行实际的 DOM 操作
- Layout:执行 DOM 操作后的相关操作
// 更新队列结构
type UpdateQueue < State > = {
baseState: State,
firstBaseUpdate: Update < State > | null,
lastBaseUpdate: Update < State > | null,
shared: SharedQueue < State > ,
callbacks: Array < () => mixed > | null,
};
type SharedQueue < State > = {
pending: Update < State > | null,
lanes: Lanes,
hiddenCallbacks: Array < () => mixed > | null,
};