前端

漫游 React 源码 - 02 - 渲染流程

React 调用过程

记录 React 调用过程,根据调用的方法名,方便阅读源码实现。

const root = ReactDOM.createRoot(document.getElementById('root')); root.render( < App / > );

程序启动,首先会调用 ReactDOM.createRoot 方法,创建一个 FiberRoot 对象,表示 React 应用的根节点。之后会调用 render 方法,将 React 应用渲染到 DOM 中。

ReactDOM.createRoot

  1. 调用createFiberRoot, 创建一个 FiberRootNode 对象,这是整个React应用的顶层节点,也可以理解成顶层容器。
  2. 之后会创建一个 Fiber 对象,HostRoot,作为Fiber 树的跟节点。FiberRootNode 的current会指向 HostRoot。
  3. 调用RootNode的 render 方法,将 React 应用渲染到 DOM 中。

render

  1. 调用 updateContainer 方法,将渲染任务添加到更新队列中。
  2. updateContainer 会创建一个 update 对象,并且调用 enqueueUpdate 方法,将 update 对象添加到更新队列中。
  3. 调用 scheduleUpdateOnFiber 方法,调度更新任务:标记根节点有待处理的更新,确保根节点被调度。
  4. scheduleUpdateOnFiber 会根据更新的优先级选择同步或异步方式处理:
    • 同步更新:直接调用 performSyncWorkOnRoot
    • 异步更新:将任务交给 Scheduler 调度
  5. performSyncWorkOnRootperformConcurrentWorkOnRoot 被调用,开始实际的渲染工作。
  6. 调用 renderRootSyncrenderRootConcurrent 进行渲染工作,这个过程包括: - "递" 阶段:从根节点开始,深度优先遍历整个组件树,为每个组件创建或更新 Fiber 节点。(beginWork) - "归" 阶段:收集所有副作用(如 DOM 更新),准备提交阶段。(completeWork)
  7. 渲染完成后,调用 commitRoot 进入提交阶段,将变更应用到实际的 DOM 中。(commitRootWhenReady)
  8. 提交阶段分为三个子阶段:
    • 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, };
Previous
React - 漫游源码1