React 核心流程与机制总结

6 阅读5分钟

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(){
     //1.创建了一个root对象
    const root = createContainer(
        container,// document.getElementById("root")!
        ...
  );
   // 2.标记为根节点
   markContainerAsRoot(root.current, container);
   //3.
  return new ReactDOMRoot(root);
}

2. 渲染 / 更新流程(render/setState 触发)

关键步骤(分阶段)
阶段核心函数作用总结
调度阶段updateContainer1. 调用 requestUpdateLane 分配优先级 Lane2. 调用 updateContainerImpl
updateContainerImpl1. createUpdate 创建 Update 对象(含 lane、payload)2. enqueueUpdate 入队更新队列3. scheduleUpdateOnFiber 触发调度
渲染阶段workLoop循环处理 Fiber 节点(同步:workLoopSync;并发:workLoopConcurrent)
performUnitOfWork1. beginWork(Diff 新老 Fiber,生成 WorkInProgress 树)2. completeWork(收集副作用,创建 DOM)
提交阶段commitRoot1. 执行 DOM 操作(插入 / 更新 / 删除)2. 切换 Current 树为 WorkInProgress 树3. 执行副作用(如 useEffect)
经典示例:setState 完整流程(点击按钮更新计数)
  1. 触发更新:点击按钮→调用 setCount→触发用户交互事件(DiscreteEventPriority)
  1. 分配优先级:requestUpdateLane 分配高优先级 Lane(如 InputContinuousLane)
  1. 创建 Update:createUpdate 生成 Update 对象(payload=count+1,lane = 高优先级)
  1. 入队更新:enqueueUpdate 将 Update 加入 Counter 组件 Fiber 的 updateQueue(环形链表)
  1. 调度渲染:scheduleUpdateOnFiber 标记 Root 的 pendingLanes→唤醒 Scheduler
  1. 渲染阶段
    • beginWork:处理 Counter Fiber→processUpdateQueue 计算新 state→Diff 子节点(无变化则 Bailout)
    • completeWork:收集副作用(无 DOM 操作,仅 state 更新)
  1. 提交阶段:更新 Counter 的 memoizedState→修改 DOM 文本(0→1)

三、关键机制(核心考点)

1. 优先级调度:Lane 模型

优先级等级代表 Lane 常量二进制(示例)适用场景渲染模式
最高(同步)SyncLane0b0000000000000000000000000000001用户输入、点击、flushSyncworkLoopSync
InputContinuousLane0b0000000000000000000000000000100滚动、拖动workLoopConcurrent
中(默认)DefaultLane0b0000000000000000000000000010000网络请求后更新、普通 setStateworkLoopConcurrent
TransitionLanes(16 条)0b0000000000000000000000001000000startTransition、useDeferredValueworkLoopConcurrent
最低(空闲)IdleLane0b0100000000000000000000000000000后台同步、非紧急任务workLoopConcurrent

核心逻辑:二进制位运算(&/|)比较优先级,低位数(高优先级)可中断高位数(低优先级);低优先级任务超时(如 5 秒)会升级为同步优先级,避免 “饥饿”。

2. 并发渲染:workLoop 两种模式对比

对比维度workLoopSync(同步)workLoopConcurrent(并发)
循环条件while (workInProgress !== null)while (workInProgress !== null && !shouldYield())
可中断性不可中断,一次性执行完所有 Fiber可中断,时间片(5ms)耗尽或高优先级任务触发时暂停
适用场景高优先级任务(用户输入、flushSync)低优先级任务(Transition、网络更新)
核心依赖无(直接执行)shouldYield ()(时间片 + 优先级判断)

3. Diff 算法:高效复用 Fiber(TodoList 示例)

核心规则(列表 Diff)
  1. key 匹配:优先根据 key 找到相同组件,避免错位(无 key 则按索引,易出错)
  1. 类型匹配:组件类型(如 TodoItem)相同才复用,不同则销毁重建
  1. Bailout 优化:若 props、state、context 均无变化,跳过子树渲染(直接复用 Fiber)
示例:点击添加 TodoItem
  • 旧列表:TodoItem1(id1)、TodoItem2(id2)
  • 新列表:TodoItem1、TodoItem2、TodoItem3(id3,新)
  • Diff 过程
    1. 复用 TodoItem1/2(key + 类型匹配,props 无变化→Bailout)
    1. 新增 TodoItem3(key 不存在→创建新 Fiber,标记 Placement)
    1. Commit 阶段仅插入 TodoItem3 的 DOM,不修改其他节点

4. 双缓存机制:Current 树 vs WorkInProgress 树

树类型作用关联方式
Current 树对应当前 DOM 状态,只读Fiber.alternate → WorkInProgress 树
WorkInProgress 树待渲染的临时树,可修改Fiber.alternate → Current 树

核心流程

  1. 渲染阶段:基于 Current 树创建 WorkInProgress 树,处理更新与 Diff
  1. 提交阶段:将 WorkInProgress 树切换为 Current 树,完成 DOM 更新
  1. 优势:避免直接修改 DOM 导致的页面闪烁,支持中断与恢复

四、高频 API 关联机制

API对应机制核心作用
ReactDOM.flushSyncforceSync=true→workLoopSync强制同步更新,阻塞其他任务
startTransition标记为 TransitionLane(低优先级)非紧急更新,不阻塞用户交互
useDeferredValue基于 TransitionLane,延迟更新值避免低优先级值更新导致的界面抖动
React.memo触发 Bailout 优化,对比 props减少无必要的组件重渲染
useEffect提交阶段执行副作用(commitHookEffectList)处理 DOM 操作后逻辑,避免阻塞渲染阶段