React 核心流程与机制总结
一、Fiber 结构核心字段(必记)
| 类别 | 关键字段 | 作用总结 |
|---|
| 身份标识 | tag | 标记 Fiber 类型(如 HostRoot、ClassComponent、HostComponent) |
| key/elementType/type | 确定组件身份,Diff 时判断是否复用 |
| 树形关系 | return/child/sibling | 构建 Fiber 树的单向链表(父→子→兄弟),实现深度优先遍历 |
| 状态与属性 | memoizedProps/memoizedState | 缓存上次渲染的 props 和 state,Diff 时对比新值 |
| pendingProps | 本次渲染待处理的 props,Commit 后转为 memoizedProps |
| 更新队列 | updateQueue | 存储待处理的 Update 对象(环形链表结构,O (1) 入队效率) |
| 优先级 | lanes/childLanes | 标记当前 Fiber 及子树的优先级(Lane 模型,二进制位表示) |
| 副作用 | flags/subtreeFlags | 记录需执行的 DOM 操作(Placement 插入、Update 更新、Deletion 删除) |
| deletions | 存储子树中需删除的 Fiber 节点 |
| 双缓存 | alternate | 连接 Current 树(当前 DOM 对应)与 WorkInProgress 树(待渲染),切换实现更新 |
二、核心流程:从 createRoot 到页面更新
1. 初始化流程(createRoot)
export function createRoot(){
const root = createContainer(
container,
...
);
markContainerAsRoot(root.current, container);
return new ReactDOMRoot(root);
}
2. 渲染 / 更新流程(render/setState 触发)
关键步骤(分阶段)
| 阶段 | 核心函数 | 作用总结 |
|---|
| 调度阶段 | updateContainer | 1. 调用 requestUpdateLane 分配优先级 Lane2. 调用 updateContainerImpl |
| updateContainerImpl | 1. createUpdate 创建 Update 对象(含 lane、payload)2. enqueueUpdate 入队更新队列3. scheduleUpdateOnFiber 触发调度 |
| 渲染阶段 | workLoop | 循环处理 Fiber 节点(同步:workLoopSync;并发:workLoopConcurrent) |
| performUnitOfWork | 1. beginWork(Diff 新老 Fiber,生成 WorkInProgress 树)2. completeWork(收集副作用,创建 DOM) |
| 提交阶段 | commitRoot | 1. 执行 DOM 操作(插入 / 更新 / 删除)2. 切换 Current 树为 WorkInProgress 树3. 执行副作用(如 useEffect) |
经典示例:setState 完整流程(点击按钮更新计数)
- 触发更新:点击按钮→调用 setCount→触发用户交互事件(DiscreteEventPriority)
- 分配优先级:requestUpdateLane 分配高优先级 Lane(如 InputContinuousLane)
- 创建 Update:createUpdate 生成 Update 对象(payload=count+1,lane = 高优先级)
- 入队更新:enqueueUpdate 将 Update 加入 Counter 组件 Fiber 的 updateQueue(环形链表)
- 调度渲染:scheduleUpdateOnFiber 标记 Root 的 pendingLanes→唤醒 Scheduler
- 渲染阶段:
-
- beginWork:处理 Counter Fiber→processUpdateQueue 计算新 state→Diff 子节点(无变化则 Bailout)
-
- completeWork:收集副作用(无 DOM 操作,仅 state 更新)
- 提交阶段:更新 Counter 的 memoizedState→修改 DOM 文本(0→1)
三、关键机制(核心考点)
1. 优先级调度:Lane 模型
| 优先级等级 | 代表 Lane 常量 | 二进制(示例) | 适用场景 | 渲染模式 |
|---|
| 最高(同步) | SyncLane | 0b0000000000000000000000000000001 | 用户输入、点击、flushSync | workLoopSync |
| 高 | InputContinuousLane | 0b0000000000000000000000000000100 | 滚动、拖动 | workLoopConcurrent |
| 中(默认) | DefaultLane | 0b0000000000000000000000000010000 | 网络请求后更新、普通 setState | workLoopConcurrent |
| 低 | TransitionLanes(16 条) | 0b0000000000000000000000001000000 | startTransition、useDeferredValue | workLoopConcurrent |
| 最低(空闲) | IdleLane | 0b0100000000000000000000000000000 | 后台同步、非紧急任务 | workLoopConcurrent |
核心逻辑:二进制位运算(&/|)比较优先级,低位数(高优先级)可中断高位数(低优先级);低优先级任务超时(如 5 秒)会升级为同步优先级,避免 “饥饿”。
2. 并发渲染:workLoop 两种模式对比
| 对比维度 | workLoopSync(同步) | workLoopConcurrent(并发) |
|---|
| 循环条件 | while (workInProgress !== null) | while (workInProgress !== null && !shouldYield()) |
| 可中断性 | 不可中断,一次性执行完所有 Fiber | 可中断,时间片(5ms)耗尽或高优先级任务触发时暂停 |
| 适用场景 | 高优先级任务(用户输入、flushSync) | 低优先级任务(Transition、网络更新) |
| 核心依赖 | 无(直接执行) | shouldYield ()(时间片 + 优先级判断) |
3. Diff 算法:高效复用 Fiber(TodoList 示例)
核心规则(列表 Diff)
- key 匹配:优先根据 key 找到相同组件,避免错位(无 key 则按索引,易出错)
- 类型匹配:组件类型(如 TodoItem)相同才复用,不同则销毁重建
- Bailout 优化:若 props、state、context 均无变化,跳过子树渲染(直接复用 Fiber)
示例:点击添加 TodoItem
- 旧列表:TodoItem1(id1)、TodoItem2(id2)
- 新列表:TodoItem1、TodoItem2、TodoItem3(id3,新)
-
- 复用 TodoItem1/2(key + 类型匹配,props 无变化→Bailout)
-
- 新增 TodoItem3(key 不存在→创建新 Fiber,标记 Placement)
-
- Commit 阶段仅插入 TodoItem3 的 DOM,不修改其他节点
4. 双缓存机制:Current 树 vs WorkInProgress 树
| 树类型 | 作用 | 关联方式 |
|---|
| Current 树 | 对应当前 DOM 状态,只读 | Fiber.alternate → WorkInProgress 树 |
| WorkInProgress 树 | 待渲染的临时树,可修改 | Fiber.alternate → Current 树 |
核心流程:
- 渲染阶段:基于 Current 树创建 WorkInProgress 树,处理更新与 Diff
- 提交阶段:将 WorkInProgress 树切换为 Current 树,完成 DOM 更新
- 优势:避免直接修改 DOM 导致的页面闪烁,支持中断与恢复
四、高频 API 关联机制
| API | 对应机制 | 核心作用 |
|---|
| ReactDOM.flushSync | forceSync=true→workLoopSync | 强制同步更新,阻塞其他任务 |
| startTransition | 标记为 TransitionLane(低优先级) | 非紧急更新,不阻塞用户交互 |
| useDeferredValue | 基于 TransitionLane,延迟更新值 | 避免低优先级值更新导致的界面抖动 |
| React.memo | 触发 Bailout 优化,对比 props | 减少无必要的组件重渲染 |
| useEffect | 提交阶段执行副作用(commitHookEffectList) | 处理 DOM 操作后逻辑,避免阻塞渲染阶段 |