菜单

React 协调器 (Reconciler)

相关源文件

React 协调器 (React Reconciler) 是 React 的核心引擎,它实现了协调算法(有时称为“diffing”算法)。它负责计算两个 React 元素树之间的差异,确定在 DOM 或其他渲染环境中需要更新的内容,并协调渲染过程。协调器是平台无关的,允许 React 支持多种渲染环境,如 DOM(web)、原生移动平台和自定义渲染器。

本文档涵盖了 React 协调器的内部架构和关键概念。有关 React DOM 等特定渲染目标的信息,请参阅 渲染目标

架构概述

React 协调器在 React 架构中居于核心地位,它连接了 React 的核心概念与特定于平台的渲染实现。

来源

Fiber 架构

React 协调器围绕“fiber”(即表示组件树中组件的工作单元)的概念构建。此架构在 React 16 中取代了之前的基于堆栈的协调器,并支持增量渲染、基于优先级的更新和更好的错误边界等功能。

Fiber 数据结构

Fiber 是一个 JavaScript 对象,代表一个工作单元和 React 组件树中的一个节点。它包含有关组件、其输入和输出的信息。

Fiber 的关键属性

  • tag:标识 Fiber 的类型(例如,函数组件、类组件、宿主组件)
  • type:与此 Fiber 相关联的函数或类
  • stateNode:引用宿主环境实例(例如 DOM 节点)或类实例
  • return, child, sibling:形成 Fiber 树结构的指针
  • memoizedState:组件的当前状态
  • updateQueue:待处理的状态更新队列
  • flags:标识需要执行何种工作的标志(例如,放置、更新、删除)
  • lanes:表示更新的优先级级别

来源

协调过程

协调过程是决定 UI 中需要更新内容的核核心算法。它包含多个阶段:

渲染阶段(协调)

渲染阶段计算所需的更改,但不会将其应用于宿主环境。此阶段可以中断和恢复,因此适用于时间分片和优先级处理。

  1. Begin Work:从上到下处理组件,创建或更新 Fiber。
  2. Complete Work:从下到上处理,完成每个 Fiber 上的工作。

这些阶段创建了一个工作中的 Fiber 树(WIP),代表 UI 的下一个状态。

来源

提交阶段

提交阶段将计算出的更改应用于宿主环境(例如 DOM)。与渲染阶段不同,它同步运行且不可中断。

  1. 变异前阶段 (Before Mutation Phase):处理 DOM 变异前所需的操作(例如类组件中的 getSnapshotBeforeUpdate)。
  2. 变异阶段 (Mutation Phase):应用 DOM 更新(插入、更新、删除)。
  3. 布局阶段 (Layout Phase):运行需要更新 DOM 的副作用(例如 componentDidMount、componentDidUpdate)。
  4. 被动副作用阶段 (Passive Effects Phase):稍后运行被动副作用(例如 useEffect 回调)。

来源

工作循环和调度

Fiber 工作循环是协调过程的核心,它协调工作的执行时间和方式。

工作循环可以在两种模式下运行:

  1. 同步模式 (Synchronous Mode):不向浏览器让步地处理工作,确保立即应用更新。
  2. 并发模式 (Concurrent Mode):可以暂停和恢复工作,向浏览器让步以保持响应性。

来源

Lanes:优先级系统

React 使用“lanes”的概念来表示更新的优先级。Lanes 允许 React:

  1. 将更新分组为不同的优先级级别
  2. 独立跟踪多个更新
  3. 当被更高优先级的工作取代时,丢弃低优先级更新
  4. 处理过渡和并发特性

关键的 Lane 相关操作:

  • requestUpdateLane:确定更新的适当 Lane
  • markRootUpdated:将根标记为在特定 Lane 中有待处理的工作
  • getNextLanes:选择在当前工作循环中要处理哪些 Lane

来源

Hooks 实现

React Hooks 在协调器内部实现。每个 Hook 都会在 Fiber 的 memoizedState 属性中创建一个链表对象。

当组件渲染时:

  1. 根据是挂载还是更新,设置调度器。
  2. 调用组件函数,并按顺序处理 Hooks。
  3. 对于更新,Hooks 按位置与之前的版本匹配。

来源

状态和副作用管理

React 使用 Fiber 架构管理状态更新和副作用:

  • 状态更新:在 Fiber 的 updateQueue 中排队,并在渲染阶段处理。
  • 副作用:使用副作用标志在 Fiber 上标记,并在提交阶段处理。

不同类型的副作用:

  • 布局副作用 (useLayoutEffect):在 DOM 变异后同步运行。
  • 被动副作用 (useEffect):在浏览器绘制后异步运行。
  • Ref 更新:在提交阶段应用。

来源

更新管理

协调器处理两种主要的更新类型:

  1. 组件驱动的更新:由 setState、useState 更新函数或 forceUpdate 触发。
  2. 外部更新:由 ReactDOM.render 或其他顶级 API 触发。

每个更新都与以下内容相关联:

  • 优先级级别(Lane)
  • 有效负载(例如,新状态或属性)
  • 可能是在处理更新后执行的回调

来源

错误处理和 Suspense

协调器包含对错误和 Suspense 的特殊处理:

  1. 错误边界 (Error Boundaries):当渲染过程中发生错误时,协调器会在 Fiber 树中向上搜索错误边界。
  2. Suspense:组件可以暂停渲染(抛出 Promise),协调器会捕获并显示备用内容。

来源

公共 API

协调器为渲染器提供了一个公共 API:

这些函数由 ReactDOM 等渲染器用于与协调器交互。

来源

总结

React 协调器是一个复杂的系统,它:

  1. 实现 Fiber 架构以实现增量渲染
  2. 协调 React 元素树的协调过程
  3. 根据优先级调度更新
  4. 管理组件状态和副作用
  5. 为并发模式、Suspense 和 Transitions 等高级功能奠定基础

其设计使 React 能够高效、灵活并适应不同的渲染环境,同时提供一致的开发体验。