React 核心流程总述

一、主流程总览

scss 复制代码
┌──────────────────────────────────────────────────────────────┐
│  挂载:createContainer → createFiberRoot → createHostRootFiber│
│  更新:updateContainer → createUpdate → enqueueUpdate       │
│        → scheduleUpdateOnFiber                              │
└──────────────────────────────────────────────────────────────┘
                                │
                                ▼
                    ┌───────────────────────┐
                    │  ensureRootIsScheduled │ ← ReactFiberRootScheduler
                    │  (接入 Scheduler)      │
                    └───────────────────────┘
                                │
                    ┌───────────▼───────────------------------┐
                    │  performConcurrentWorkOnRoot │  ← 启动并发渲染
                    │  (由 Scheduler 回调)         │
                    └───────────┬───────────------------------┘
                                │
                    ┌───────────▼───────────┐
                    │  renderRootConcurrent │ ← 并发渲染循环(可中断)
                    │  或 renderRootSync    │ ← 同步渲染循环(不可中断,用于 LegacyRoot)
                    └───────────┬───────────┘
                                │
                     ┌──────────▼──────────┐
                     │  prepareFreshStack   │ ← 创建 workInProgress 树
                     └──────────┬──────────┘
                                │
              ┌─────────────────▼─────────────────┐
              │   workLoopConcurrent / workLoopSync │ ← 逐个 fiber 执行
              │  ┌─────────────────────────────┐   │
              │  │  performUnitOfWork(fiber)   │   │ ← 执行 beginWork,若无子节点则 completeUnitOfWork
              │  │  ├─ beginWork()      [递]   │   │
              │  │  │   → 返回 child fiber     │   │
              │  │  └─ completeUnitOfWork()[归] │   │ ← 归阶段:sibling → 父 completeWork
              │  │      → completeWork()       │   │
              │  └─────────────────────────────┘   │
              │    并发模式: shouldYield() 控制中断  │
              └─────────────────┬─────────────────┘
                                │
                    ┌───────────▼───────────┐
                    │  finishConcurrentRender│
                    │  → completeRoot        │ ← 渲染完成,提交前准备
                    └───────────┬───────────┘
                                │
                    ┌───────────▼───────────┐
                    │  commitRoot           │ ← 三阶段提交
                    │  ├─ commitBeforeMutation │ Snapshot
                    │  ├─ commitMutation      │ DOM 操作
                    │  └─ commitLayout        │ useLayoutEffect
                    └───────────────────────┘

二、挂载(createRoot → 首次渲染)

scss 复制代码
createContainer(container, ConcurrentRoot, ...)
  → createFiberRoot(...)
    → createHostRootFiber(ConcurrentRoot) → Fiber(HostRoot)
    → initializeUpdateQueue(fiber)
    → return FiberRoot

updateContainer(<App />, root, null, null)
  → requestUpdateLane → SyncLane
  → createUpdate(lane) → {payload: {element: <App/>}}
  → enqueueUpdate(rootFiber, update, lane)
  → scheduleUpdateOnFiber(root, rootFiber, lane)
    → markRootUpdated(root, lane)
    → ensureRootIsScheduled(root)
      → Scheduler.scheduleCallback(priority, performConcurrentWorkOnRoot)

三、渲染循环(renderRootConcurrent)

scss 复制代码
renderRootConcurrent(root, lanes)
  → prepareFreshStack(root, lanes)
    → createWorkInProgress(root.current, null) → 新的 workInProgress 根
    → workInProgress = root.current.alternate

  → workLoopConcurrent():
    while (workInProgress !== null && !shouldYield()) {
      performUnitOfWork(workInProgress)
    }

performUnitOfWork(fiber):
  next = beginWork(current, fiber, renderLanes)  // 递
  if (next === null):
    completeUnitOfWork(fiber)                     // 归
  else:
    workInProgress = next                          // 继续深入

completeUnitOfWork(fiber):
  do:
    completeWork(current, fiber, renderLanes)   // 完成当前
    if (sibling): workInProgress = sibling; return
    fiber = return                               // 回到父节点
  while (fiber !== null)

递阶段

作用:根据 fiber.tag 分发到不同处理函数,返回子 fiber。

scss 复制代码
beginWork(current, workInProgress, renderLanes)
    ↓
switch (workInProgress.tag):
  ├── FunctionComponent → updateFunctionComponent()
  │     → renderWithHooks() → 执行函数体 → reconcileChildren()
  ├── ClassComponent → updateClassComponent()
  │     → 实例化/更新 → 调用生命周期 → reconcileChildren()
  ├── HostRoot → updateHostRoot()
  │     → processUpdateQueue() → reconcileChildren()
  ├── HostComponent → updateHostComponent()
  │     → 处理 DOM 属性 → reconcileChildren()
  ├── HostText → updateHostText()
  ├── Fragment → updateFragment()
  ├── ContextProvider → updateContextProvider()
  │     → pushProvider() → propagateContextChange()
  ├── ContextConsumer → updateContextConsumer()
  │     → readContext() → 订阅变化
  ├── SuspenseComponent → updateSuspenseComponent()
  ├── ForwardRef → updateForwardRef()
  │     → renderWithHooks() → reconcileChildren()
  ├── MemoComponent → updateMemoComponent()
  │     → shallowEqual 比较 props → 跳过或深入
  ├── OffscreenComponent → updateOffscreenComponent()
  └── ActivityComponent → updateActivityComponent()
    ↓
若返回 null → 进入 completeUnitOfWork
若返回 fiber → 继续 workLoop(深度优先遍历)

bailout 优化 :当 props/state/context 未变化且 lanes 不匹配时,bailoutOnAlreadyFinishedWork() 跳过子树。

归阶段

作用:自底向上完成 fiber 处理。为 HostComponent 创建/更新 DOM 实例。

scss 复制代码
completeWork(current, workInProgress, renderLanes)
    ↓
switch (workInProgress.tag):
  ├── HostComponent → 
  │     mount: createInstance() → appendAllChildren() → 设置属性
  │     update: diffProperties() → 记录 updatePayload
  ├── HostText → createTextInstance() / 更新文本
  ├── HostRoot → 完成根节点
  ├── HostSingleton → body/html/head 特殊处理
  ├── ContextProvider → popProvider() 回滚上下文
  ├── SuspenseComponent → 决定挂起/恢复
  ├── OffscreenComponent → 处理隐藏/显示
  └── ViewTransitionComponent → ViewTransition 处理
    ↓
bubbleProperties(workInProgress)
  → subtreeFlags |= child.subtreeFlags | child.flags
  → childLanes = mergeLanes(child.childLanes, child.lanes)

bubbleProperties:将子树的 flags 和 lanes 冒泡到父 fiber,使根能汇总所有副作用。

四、提交阶段(commitRoot)

作用:将渲染结果提交到 DOM。分三个子阶段执行。

scss 复制代码
commitRoot(root, finishedWork, ...)
  → 执行全局副作用通知
  → flushPendingEffects()  // 先处理残留的 effect
  → 设置 pendingEffectsRemainingLanes
  → 根据 status 决定是否提交

commitRootImpl(root, ...)
  → commitBeforeMutationEffects(finishedWork)
    → Snapshot flag: getSnapshotBeforeUpdate
    → 调度 Passive effects(setTimeout/flushPassiveEffects)
  → commitMutationEffects(finishedWork, root)
    → Placement: DOM 插入
    → Update: DOM 属性更新
    → Ref: 更新/清理 ref
    → ChildDeletion: 删除 DOM + 卸载 effects
  → commitAfterMutationEffects(root)
  → commitLayoutEffects(finishedWork, root)
    → useLayoutEffect 挂载/更新
    → componentDidMount/Update
    → 赋值 ref
  → flushPassiveEffects()  // 异步执行 useEffect

Mutation 阶段

commitMutationEffects 遍历 finishedWork.flags

scss 复制代码
Placement → commitPlacement() → appendChild / insertBefore (DOM 插入)
Update → commitUpdate() → diffProperties 写入 DOM
ChildDeletion → commitDeletion() → 卸载 effects,移除 DOM
Ref → commitDetachRef() / commitAttachRef()
Hydrating → commitHydratedDOM()
Visibility → Offscreen 隐藏/显示
ContentReset → resetTextContent()

Layout 阶段

sql 复制代码
commitLayoutEffects(finishedWork)
  → 遍历 fiber 树
  → Callback flag → commitCallbacks(componentDidMount/Update 回调)
  → Ref flag → commitAttachRef(挂载 ref)
  → Update flag → commitLayoutEffectOnFiber(执行 useLayoutEffect)
相关推荐
光影少年2 小时前
react状态管理
前端·react.js·前端框架
珎珎啊2 小时前
React 和 Vue 3的区别
前端·vue.js·react.js
Bigger3 小时前
mini-cc 终端 UI:用 React 写 CLI 是什么体验
前端·react.js·ai编程
吹个口哨写代码4 小时前
IIS 部署 Vue/React 单页应用 (SPA) 刷新页面 404/403.18 报错原因及终极解决方案
前端·vue.js·react.js
喵个咪15 小时前
基于 Taro 的 Headless CMS 多端前端架构:技术解析与二次开发导引
前端·react.js·taro
假如让我当三天老蒯1 天前
React+TS 项目结构(自学项目用)
前端·react.js
vim怎么退出1 天前
Dive into React——Fiber架构
react.js·源码阅读
光影少年1 天前
react中的Context 为什么会导致性能问题?
前端·javascript·react.js