返回

React 源码学习之 commit 阶段

前端

前言

在上一篇文章中,我们学习了 React 的调度机制,了解了如何将更新任务调度到浏览器主线程。在这篇文章中,我们将继续深入 React 源码,剖析 commit 阶段的工作流程。

commit 阶段是 React 渲染过程的最后一个阶段,也是最关键的阶段之一。在这个阶段,React 将更新后的 Fiber 树转换为真实的 DOM 节点,并将其插入到页面中。

commitRoot 方法

commitRoot 方法是 commit 阶段工作的起点。它接受一个 FiberRootNode 类型的参数 root,并负责将 root 节点及其子节点提交到页面中。

在 commitRoot 方法中,首先会调用 performWorkOnRoot 函数对 root 节点及其子节点进行必要的更新。然后,调用 commitRootImpl 函数将更新后的 Fiber 树转换为真实的 DOM 节点,并将其插入到页面中。

performWorkOnRoot 函数

performWorkOnRoot 函数是 React 调度器中的一个核心函数。它负责对 Fiber 树进行更新,并生成一个新的 Fiber 树。

performWorkOnRoot 函数的工作流程大致如下:

  1. 调用 reconcileChildren 函数为 root 节点生成一个新的子 Fiber 树。
  2. 调用 completeWork 函数完成 root 节点的更新。
  3. 调用 commitRootImpl 函数将更新后的 Fiber 树转换为真实的 DOM 节点,并将其插入到页面中。

reconcileChildren 函数

reconcileChildren 函数负责为 root 节点生成一个新的子 Fiber 树。它会遍历 root 节点的子节点,并为每个子节点生成一个新的 Fiber 节点。

在 reconcileChildren 函数中,首先会调用 createElement 函数创建一个新的 Fiber 节点。然后,调用 updateSlot 函数更新 Fiber 节点的属性。最后,调用 reconcileChildFibers 函数为 Fiber 节点的子节点生成新的 Fiber 树。

completeWork 函数

completeWork 函数负责完成 root 节点的更新。它会遍历 root 节点的子节点,并为每个子节点调用 completeWork 函数。

在 completeWork 函数中,首先会调用 completeUnitOfWork 函数完成子 Fiber 节点的更新。然后,调用 completeWork 函数完成 root 节点的更新。

commitRootImpl 函数

commitRootImpl 函数负责将更新后的 Fiber 树转换为真实的 DOM 节点,并将其插入到页面中。

commitRootImpl 函数的工作流程大致如下:

  1. 调用 createDOMElement 函数为每个 Fiber 节点创建一个新的 DOM 节点。
  2. 调用 updateDOMProperties 函数更新 DOM 节点的属性。
  3. 调用 insertChildIntoParent 函数将 DOM 节点插入到父 DOM 节点中。

useEffect

useEffect 是 React 中的一个钩子函数,用于在组件生命周期的不同阶段执行副作用操作。useEffect 函数有两种形式:

  • useEffect(callback, []):在组件挂载和更新时执行 callback 函数。
  • useEffect(callback, [deps]):在组件挂载和更新时执行 callback 函数,但只有当 deps 数组中的值发生变化时才会执行。

useEffect 函数的实现原理大致如下:

  1. 在组件挂载时,将 callback 函数存储在一个数组中。
  2. 在组件更新时,比较 deps 数组中的值是否发生变化。
  3. 如果 deps 数组中的值发生变化,则执行 callback 函数。

总结

在本文中,我们学习了 React commit 阶段的工作流程,包括 commitRoot 方法、performWorkOnRoot 函数、reconcileChildren 函数、completeWork 函数、commitRootImpl 函数和 useEffect 函数的实现原理。通过对这些函数的学习,我们对 React 的工作机制有了更深入的理解。