文章目录

React 原理与源码学习笔记

适合目标:系统理解 React 的运行机制,能把 Fiber、Diff、Hooks、调度、批处理这些高频源码面试题讲清楚。
学习定位:这一份偏“能解释原理、能看懂主干源码、能回答底层问题”。
学习原则:先搭地图,再看细节;先讲流程,再钻源码;先掌握主干概念,再补实现细节。


目录

  1. 学习总览
  2. 看源码前先建立地图
  3. React 整体运行流程
  4. Fiber 架构
  5. 双缓冲机制
  6. 调度、优先级与时间切片
  7. Diff 与 Reconciliation
  8. Render 与 Commit
  9. Hooks 原理
  10. 更新队列与批处理
  11. React 18 并发特性
  12. 事件系统与上下文更新
  13. 常见源码面试题
  14. 8 小时源码学习规划
  15. 一页速记总结
  16. 背诵口诀
  17. 源码阅读路线

1. 学习总览

1.1 为什么要学 React 原理

只会写 React 和理解 React 底层,是两个层次。

学源码和原理的意义:

  1. 面试能讲清楚“为什么”
  2. 性能优化更有依据
  3. 理解 Hook、渲染、更新时机不再靠死记
  4. 遇到复杂问题时更容易定位本质

1.2 React 原理到底学什么

你真正需要掌握的主线只有这几条:

  1. 组件更新是怎么被调度的
  2. React 为什么要引入 Fiber
  3. 新旧节点是怎么比较的
  4. Hook 状态为什么靠顺序关联
  5. 更新为什么能批处理、可中断、可恢复

1.3 React 源码学习主线

可以记成:

JSX -> React Element -> Fiber -> 调度 -> Render -> Commit -> DOM 更新

也就是说:

  1. JSX 最终变成元素对象
  2. 元素对象对应 Fiber 节点
  3. Fiber 节点组成 Fiber 树
  4. 更新被调度
  5. Render 阶段生成新的工作树
  6. Commit 阶段把变更提交到宿主环境

1.4 面试里最常考的底层话题

  1. 为什么需要 Fiber
  2. React Diff 为什么是 O(n)
  3. key 的作用是什么
  4. render 和 commit 有什么区别
  5. useState 为什么不能条件调用
  6. useEffect 为什么有清理函数
  7. React 18 自动批处理和并发更新是什么

2. 看源码前先建立地图

2.1 React 不是一个包,而是一组包

React 仓库不是只有一个核心文件,而是由多个包组成。

从理解层面可以先记住几个重点:

  1. react
  2. react-dom
  3. react-reconciler
  4. scheduler
  5. shared

2.2 这些包分别负责什么

react

负责暴露开发者常用 API,例如:

  1. useState
  2. useEffect
  3. createContext
  4. memo

react-dom

负责和浏览器 DOM 环境打交道,例如:

  1. 创建 root
  2. 挂载到页面
  3. 处理宿主环境更新

react-reconciler

这是 React 内部协调器的核心,很多 Fiber、Diff、Hook、调度主逻辑都在这里。

scheduler

负责调度任务,安排不同优先级的工作。

shared

放一些多个包共享的工具和常量。

2.3 学源码时最容易犯的错

  1. 一上来就逐行啃源码
  2. 没有流程图,只盯实现细节
  3. 把不同版本实现细节混在一起
  4. 把“教学化理解”和“真实实现”混为一谈

2.4 正确阅读策略

推荐顺序:

  1. 先理解概念和整体流程
  2. 再理解 Fiber 结构
  3. 再理解 render/commit
  4. 再理解 Hook 和 update queue
  5. 最后看调度与优先级

3. React 整体运行流程

3.1 从 JSX 到页面更新的大流程

一个典型更新过程可以理解成:

  1. JSX 被编译成 React Element
  2. React Element 被转换为 Fiber 节点
  3. 更新进入调度系统
  4. Render 阶段构建 workInProgress Fiber 树
  5. 找出需要变更的副作用
  6. Commit 阶段把副作用提交到 DOM

3.2 React Element 是什么

React Element 不是 DOM,也不是 Fiber。

它更像一个普通对象,用来描述:

  1. 元素类型
  2. key
  3. props
  4. ref

你可以把它理解成:

对界面的轻量描述对象

3.3 Fiber 又是什么

Fiber 是 React 内部的工作单元节点。

它比 React Element 更强,因为它不仅描述 UI,还承载:

  1. 更新信息
  2. 优先级
  3. 副作用标记
  4. 父子兄弟关系
  5. Hook 状态

3.4 一句话串起来

Element 更像“描述”,Fiber 更像“可调度的工作节点”。


4. Fiber 架构

Fiber 是 React 原理里最核心的知识点。

4.1 为什么需要 Fiber

早期 React 的递归协调过程有一个核心问题:

一旦开始,不能中断

如果组件树很大,更新工作会长时间占用主线程,造成:

  1. 页面卡顿
  2. 用户输入延迟
  3. 动画掉帧

所以 React 需要一种新结构,让更新工作:

  1. 可拆分
  2. 可中断
  3. 可恢复
  4. 可按优先级处理

这就是 Fiber 的意义。

4.2 Fiber 的本质

Fiber 可以理解成:

一个虚拟栈帧 + 一个工作单元 + 一个链表节点

为什么这样理解:

  1. 它能表示组件节点
  2. 它能保存当前工作进度
  3. 它能让 React 用链表结构而不是纯递归调用栈来遍历树

4.3 Fiber 节点上常见信息

面试里不用死背全部字段,但要知道它大概保存什么:

  1. tag:节点类型
  2. key:列表稳定标识
  3. type:组件/标签类型
  4. stateNode:真实 DOM 或类组件实例等
  5. return:父 Fiber
  6. child:第一个子 Fiber
  7. sibling:下一个兄弟 Fiber
  8. alternate:当前树和工作树之间的对应节点
  9. pendingProps:待处理 props
  10. memoizedProps:上次已生效 props
  11. memoizedState:上次已生效 state / Hook 链表
  12. updateQueue:更新队列
  13. flags:当前节点副作用标记
  14. subtreeFlags:子树副作用标记
  15. lanes:优先级相关信息

4.4 Fiber 的树结构为什么不是普通数组

React 常用的是:

  1. child
  2. sibling
  3. return

这种链式结构的好处:

  1. 节省内存
  2. 遍历灵活
  3. 更适合增量处理

4.5 工作单元怎么理解

React 在 render 阶段会把每个 Fiber 当成一个“工作单元”。

每做完一小块,就可以决定:

  1. 继续做
  2. 暂停
  3. 让更高优先级任务先做

4.6 Fiber 记忆口诀

Fiber 不是普通虚拟 DOM 节点,它是可调度、可中断、可恢复的工作单元。


5. 双缓冲机制

5.1 什么是双缓冲

React 内部会维护两棵树:

  1. 当前已经展示在页面上的树:current
  2. 正在构建的新树:workInProgress

这就是双缓冲思想。

5.2 为什么要有两棵树

因为 React 不希望边算边改真实 DOM。

更合理的流程是:

  1. 先基于旧树构建一棵新工作树
  2. 在新树上完成比较和副作用收集
  3. 确认无误后一次性提交

这样好处很多:

  1. 计算过程更安全
  2. 可以中断
  3. 可以恢复
  4. 页面上的旧树始终稳定

5.3 alternate 指针是什么

alternate 用来连接 current Fiber 和它对应的 workInProgress Fiber。

可以简单理解成:

current <-> workInProgress

5.4 双缓冲切换过程

  1. 页面当前使用 current 树
  2. 更新发生,React 以 current 为基础创建/复用 workInProgress 树
  3. render 阶段在 workInProgress 上工作
  4. commit 完成后,workInProgress 变成新的 current

5.5 记忆口诀

页面看 current,更新算 WIP,提交后两者交换身份。


6. 调度、优先级与时间切片

6.1 调度解决什么问题

React 不只是“更新”,还要决定:

  1. 哪个更新先做
  2. 哪个更新后做
  3. 是否需要打断当前工作
  4. 当前这一帧还能不能继续做事

这就是调度的任务。

6.2 优先级为什么重要

不是所有更新都一样紧急。

例如:

  1. 输入框输入很紧急
  2. 搜索结果列表刷新可以稍慢一点
  3. 后台低优先级更新更不紧急

React 需要区分优先级,才能让界面更流畅。

6.3 Lanes 怎么理解

现代 React 中,优先级更多通过 Lanes 这套机制表达。

你可以把 lane 理解成:

带优先级信息的更新通道

它的意义:

  1. 区分不同更新优先级
  2. 支持批量合并
  3. 支持并发调度

6.4 时间切片是什么

时间切片可以简单理解成:

把大任务拆成很多小段,在浏览器空档中分段处理

这样 React 就不需要一次把整棵树都同步算完。

6.5 requestIdleCallback 和 React 的关系

这是高频易错点。

很多教程会用 requestIdleCallback 来帮助理解“时间切片”,但你在源码和面试里最好说得更严谨:

  1. React 的调度思想可以类比空闲时间处理任务
  2. 但实际实现并不等于简单直接依赖 requestIdleCallback
  3. React 有自己的 scheduler 机制,会综合使用更稳定的调度方式

所以更稳的答法是:

React 的时间切片思想可以类比 requestIdleCallback,但真实实现是更复杂的协作式调度。

6.6 同步更新和并发更新

同步更新

优先级高,通常要尽快完成。

并发更新

允许更新过程被打断,让更紧急的任务先执行。

6.7 调度流程的理解版

可以简单记为:

  1. 更新发生
  2. React 给更新分配优先级
  3. 调度器决定什么时候执行
  4. render 阶段按优先级处理 Fiber 工作
  5. 必要时中断和恢复

6.8 记忆口诀

调度管先后,Lane 管优先级,时间切片管分段执行。


7. Diff 与 Reconciliation

React 的 Diff 题,是面试超级高频。

7.1 Reconciliation 是什么

Reconciliation 中文常译为“协调”。

它解决的问题是:

状态变了以后,React 如何比较新旧树,并决定最小更新代价

7.2 为什么 React Diff 是 O(n)

React 没有去做通用树的最优 Diff,那样复杂度太高。

React 使用了两个重要假设:

  1. 不同类型的元素会生成不同子树
  2. 同层节点通过 key 进行稳定识别

基于这两个前提,React 才能把复杂度控制在较低水平。

7.3 同层比较原则

React 默认只在同层比较节点,不会跨层做复杂移动推断。

这也是面试常问点:

为什么 React 只做同层比较?

因为这样可以显著降低算法复杂度,换来更可接受的性能和实现成本。

7.4 key 的作用

key 用来帮助 React 在同层节点中识别“谁是谁”。

没有稳定 key 时,React 容易:

  1. 误删节点
  2. 错误复用节点
  3. 导致输入状态错乱

7.5 key 用 index 有什么问题

如果列表只是静态展示,index 问题不大。

但如果列表有:

  1. 插入
  2. 删除
  3. 排序
  4. 过滤

那么 index 会让节点身份不稳定,导致:

  1. 状态错位
  2. 额外移动
  3. DOM 复用错误

7.6 Diff 时常见三种变化

  1. 新增
  2. 删除
  3. 移动 / 更新

React 会通过副作用标记把这些操作记录下来。

7.7 Diff 的理解版流程

  1. 从根开始比较新旧节点
  2. 类型不同,直接替换整棵子树
  3. 类型相同,尽量复用节点
  4. 再进入子节点比较
  5. 对列表节点借助 key 做识别
  6. 生成 Placement / Update / Deletion 等副作用信息

7.8 Diff 记忆口诀

不同类型直接换,同层比较求高效,列表比较靠 key。


8. Render 与 Commit

8.1 React 更新为什么分两个阶段

React 把更新流程拆成:

  1. render 阶段
  2. commit 阶段

这样可以把“计算”和“真正变更”分开。

8.2 Render 阶段做什么

render 阶段主要做:

  1. 处理更新队列
  2. 执行组件函数 / 生命周期相关逻辑
  3. 生成新的 Fiber 树
  4. 比较新旧节点
  5. 收集副作用

特点:

  1. 可以中断
  2. 可以恢复
  3. 不直接改真实 DOM

8.3 Commit 阶段做什么

commit 阶段主要做:

  1. 把副作用真正提交到 DOM
  2. 执行 ref 相关操作
  3. 执行 layout effect
  4. 安排 passive effect

特点:

  1. 不可中断
  2. 需要尽快完成
  3. 会直接影响用户看到的页面

8.4 beginWork 和 completeWork

这是 render 阶段里很重要的两个概念。

beginWork

主要负责:

  1. 处理当前 Fiber
  2. 计算子节点
  3. 决定是否继续向下遍历

completeWork

主要负责:

  1. 子树处理完成后的收尾
  2. 冒泡副作用标记
  3. 为宿主节点准备更新信息

8.5 Commit 的几个子阶段

理解层面可以分成:

  1. before mutation
  2. mutation
  3. layout
  4. passive effect(异步/后置)

before mutation

做提交前准备。

mutation

真正执行 DOM 插入、删除、更新。

layout

执行 useLayoutEffect、ref 相关同步逻辑。

passive effect

执行 useEffect 这类后置副作用。

8.6 为什么 render 可中断但 commit 不可中断

因为:

  1. render 阶段只是计算
  2. commit 阶段已经开始改真实界面

如果 commit 被中断,页面可能处于不一致状态。

8.7 记忆口诀

render 负责算,commit 负责改;render 可打断,commit 要一口气做完。


9. Hooks 原理

Hooks 原理和使用层最关键的桥梁,就是“顺序 + 链表 + 当前 Fiber”。

9.1 Hook 状态存在哪里

Hook 状态并不是存在函数里,而是挂在当前 Fiber 上。

可以粗略理解为:

  1. 每个函数组件对应一个 Fiber
  2. 这个 Fiber 上会挂一条 Hook 链表
  3. 每次渲染按顺序取出或创建对应 Hook 节点

9.2 为什么 Hook 不能条件调用

因为 React 不是根据 Hook 名字找状态,而是根据:

本次渲染中的调用顺序

例如第一次渲染:

  1. 第一个 Hook 是 useState
  2. 第二个 Hook 是 useEffect

如果下一次渲染你把第一个 Hook 跳过了,后面的 Hook 都会错位。

这就是规则:

Hook 必须稳定按相同顺序调用

9.3 useState 原理怎么讲

useState 本质上可以理解为:

  1. Fiber 上有对应 Hook 节点
  2. Hook 节点里保存当前状态和更新队列
  3. 调用 setter 时,不是立即改值,而是往队列里放 update
  4. 下一轮渲染时,React 取出队列依次计算新状态

9.4 useState 的更新队列

当你调用:

setCount((c) => c + 1);

React 会把这次更新包装成 update 对象,放入队列。

下一轮 render 时:

  1. 取出旧 state
  2. 按顺序处理每个 update
  3. 计算出最终 state

9.5 为什么函数式更新很重要

因为队列里每个 update 都会基于前一个结果继续算,所以函数式更新更适合多次连续更新。

9.6 useEffect 原理怎么讲

可以理解为:

  1. render 阶段记录 effect 信息
  2. 比较依赖数组,判断是否需要执行
  3. commit 后统一执行 passive effect
  4. 在下一次 effect 执行前或卸载前执行 cleanup

9.7 useEffect 为什么有清理函数

因为很多副作用都需要成对管理:

  1. 订阅和取消订阅
  2. 定时器创建和清理
  3. 事件绑定和解绑
  4. 请求开始和中止

React 让 cleanup 成为 effect 逻辑的一部分,方便资源回收。

9.8 useMemo 和 useCallback 原理怎么理解

本质都属于:

在 Hook 链表中保存上一次的依赖和结果

如果依赖没变:

  1. useMemo 复用旧值
  2. useCallback 复用旧函数引用

9.9 useReducer 原理怎么讲

你可以把它理解成 useState 的增强版:

  1. 也有 Hook 节点
  2. 也有更新队列
  3. 只是更新时会经过 reducer 计算

9.10 Hooks 原理记忆口诀

Hook 挂在 Fiber 上,靠调用顺序对应;state 走更新队列,effect 在提交后执行。


10. 更新队列与批处理

10.1 更新队列是什么

React 不会一调用 setState 就立刻同步改最终状态,而是把更新放入队列。

这样做的好处:

  1. 能合并多个更新
  2. 能按优先级处理
  3. 能在 render 阶段统一计算

10.2 类组件和函数组件都有更新队列

虽然实现细节不同,但思想类似:

  1. 收集更新
  2. 合并更新
  3. 在合适时机重新渲染

10.3 批处理是什么

批处理就是:

把同一批次里的多个更新合并处理,减少重复渲染

10.4 React 18 自动批处理

React 18 中,自动批处理覆盖了更多场景。

面试答法:

  1. 多个状态更新会尽量合并成一次渲染
  2. 这样减少性能损耗
  3. 是 React 18 的重要特性之一

10.5 为什么说 state 更新“不是同步立刻生效”

因为:

  1. 调用 setter 只是发起更新
  2. React 要把更新放入队列并调度
  3. 真正的新状态要等下一轮渲染计算后才能拿到

10.6 flushSync 怎么理解

在特殊情况下,可以使用同步刷新能力强制更早提交更新。

但面试和实际项目里要强调:

它是特殊手段,不应滥用。

10.7 记忆口诀

先入队,再调度;先合并,再渲染。


11. React 18 并发特性

11.1 并发渲染不是多线程

这是非常高频的纠错点。

React 18 的并发渲染不是说 React 开了多个线程同时执行 JS,而是:

  1. 更新工作可被打断
  2. 不同更新有不同优先级
  3. React 能让更紧急的更新先完成

11.2 startTransition / useTransition

这类能力的核心价值是:

把不那么紧急的状态更新标记为低优先级更新。

例子:

  1. 输入框文字更新很紧急
  2. 根据输入筛选大列表可以稍晚一点

11.3 Suspense 原理化理解

可以先从理解层面记:

  1. 当子树“暂时不能就绪”时
  2. React 可以先渲染 fallback
  3. 等待条件满足后再渲染真正内容

11.4 Suspense 为什么重要

它让“等待态”变成 React 渲染模型的一部分,而不是完全靠业务手写 if-else 管理。

11.5 useDeferredValue

用于把某个值的更新延后,让输入和重计算解耦。

11.6 React 18 原理答题关键词

  1. 自动批处理
  2. 可中断渲染
  3. 优先级调度
  4. 过渡更新
  5. Suspense

12. 事件系统与上下文更新

12.1 React 事件系统怎么理解

从使用层看,React 提供的是统一事件接口。

从原理角度,可以理解为:

  1. React 会做事件封装
  2. 事件分发和更新调度结合更紧密
  3. 这样有利于跨平台一致性和内部控制

12.2 为什么 React 要有自己的一层事件系统

理解角度:

  1. 统一不同浏览器行为
  2. 更好和 Fiber 更新流程协作
  3. 提供一致的开发体验

12.3 Context 更新怎么影响渲染

当 Provider 的 value 变化时,依赖这个 Context 的消费组件会重新参与更新。

所以使用 Context 时要注意:

  1. 不要把频繁变化的大对象直接整包传下去
  2. 必要时拆分多个 Context
  3. 让变化范围尽量局部

12.4 为什么 Context 容易带来性能问题

因为它的更新范围如果设计不好,会比较广。

所以面试里可以答:

  1. Context 适合中小规模共享数据
  2. 高频复杂全局状态不一定最适合 Context 直接硬扛

13. 常见源码面试题

13.1 为什么需要 Fiber

标准答法:

  1. 早期递归更新一旦开始不能中断
  2. 大树更新会长时间占用主线程
  3. Fiber 把更新拆成可中断、可恢复的工作单元
  4. 这样 React 才能实现更细粒度调度和并发能力

13.2 React Diff 为什么不是 O(n^3)

答:

  1. React 没采用通用树最优 Diff
  2. 它基于“不同类型生成不同子树”和“key 标识同层稳定节点”两个假设
  3. 只做同层比较,从而把复杂度控制在更可接受的范围

13.3 render 和 commit 区别

答:

  1. render 阶段负责计算新 Fiber 树和收集副作用
  2. commit 阶段负责真正提交 DOM 变更和执行副作用
  3. render 可中断,commit 不可中断

13.4 Hook 为什么不能条件调用

答:

  1. Hook 状态在 Fiber 上按调用顺序关联
  2. 条件调用会破坏顺序
  3. 后续 Hook 对应关系会错乱

13.5 useEffect 为什么不是同步执行

答:

  1. useEffect 属于提交后的后置副作用
  2. 它不阻塞浏览器绘制
  3. 更适合请求、订阅、日志等副作用逻辑

13.6 key 的作用是什么

答:

  1. 用来标识同层节点身份
  2. 帮助 React 在列表更新中复用节点
  3. 减少错误移动和状态错位

13.7 React 18 并发渲染是什么

答:

  1. 不是多线程
  2. 是更新过程可被打断和按优先级调度
  3. 目的是提高用户交互流畅度

13.8 自动批处理是什么

答:

  1. React 会把同一批次中的多个更新合并处理
  2. 减少重复渲染
  3. React 18 覆盖场景更广

13.9 面试回答总模板

源码题建议按这个顺序回答:

  1. 先说它解决什么问题
  2. 再说核心机制
  3. 再说流程
  4. 最后说收益和代价

14. 8 小时源码学习规划

第 1 小时:搭地图

目标:

  1. 搞懂 React、React DOM、Reconciler、Scheduler 的角色
  2. 建立从 JSX 到 DOM 的主流程

必须会:

  1. Element 和 Fiber 区别
  2. render/commit 两阶段

第 2-3 小时:Fiber 架构

目标:

  1. 搞清楚为什么需要 Fiber
  2. 理解 Fiber 节点结构
  3. 理解 child/sibling/return 和 alternate

必须会:

  1. Fiber 是什么
  2. 双缓冲是什么
  3. 工作单元是什么

第 4 小时:调度与优先级

目标:

  1. 理解调度存在的意义
  2. 理解优先级
  3. 理解时间切片思想

必须会:

  1. 为什么需要打断更新
  2. Lane 在概念上解决什么问题

第 5 小时:Diff

目标:

  1. 吃透同层比较
  2. 理解 key 的意义
  3. 理解新增/删除/移动

必须会:

  1. 为什么只比较同层
  2. 为什么 key 不能乱用 index

第 6 小时:Hooks 原理

目标:

  1. 理解 Hook 链表
  2. 理解更新队列
  3. 理解 effect 执行时机

必须会:

  1. useState 为什么不能条件调用
  2. useEffect 为什么有 cleanup

第 7 小时:React 18 并发特性

目标:

  1. 理解自动批处理
  2. 理解 transition
  3. 理解 Suspense 在渲染模型中的意义

第 8 小时:复盘 + 面试表达

建议:

  1. 自己画出 Fiber 树关系图
  2. 自己讲一遍 render/commit
  3. 自己讲一遍 useState 原理
  4. 自己讲一遍 key 和 Diff

15. 一页速记总结

15.1 Fiber

  1. Fiber 是工作单元
  2. 支持可中断、可恢复、可调度
  3. 节点之间通过 child/sibling/return 连接

15.2 双缓冲

  1. current 是当前展示树
  2. workInProgress 是正在计算的新树
  3. commit 后 WIP 变 current

15.3 调度

  1. 更新有优先级
  2. React 能按优先级安排工作
  3. 时间切片让大任务分段执行

15.4 Diff

  1. 同层比较
  2. 类型不同直接替换
  3. 列表比较依赖 key

15.5 Hooks

  1. Hook 状态挂在 Fiber 上
  2. 靠调用顺序匹配
  3. useState 走更新队列
  4. useEffect 在 commit 后执行

15.6 React 18

  1. 自动批处理
  2. 并发渲染能力
  3. 过渡更新
  4. Suspense 增强

16. 背诵口诀

16.1 Fiber 口诀

Fiber 是工作单元,可打断可恢复,替代同步递归更新。

16.2 Diff 口诀

不同类型直接换,同层节点靠 key,比的是身份不是位置。

16.3 Hooks 口诀

Hook 挂 Fiber,顺序不能乱;state 进队列,effect 提交后再算。

16.4 React 18 口诀

批处理更主动,更新可分轻重,渲染可被打断,等待态有 Suspense。


17. 源码阅读路线

17.1 第一阶段:只看概念,不抠细节

先回答这几个问题:

  1. 为什么需要 Fiber
  2. current 和 workInProgress 是什么
  3. render 和 commit 分别做什么
  4. Hook 为什么不能条件调用

17.2 第二阶段:按主线看

推荐顺序:

  1. 先看整体更新流程
  2. 再看 Fiber 和双缓冲
  3. 再看 Diff
  4. 再看 Hooks
  5. 最后看调度与优先级

17.3 第三阶段:带着问题看源码

不要问“这行代码是什么意思”,而要问:

  1. 这一段在更新流程里属于哪一步
  2. 它解决的是哪个问题
  3. 如果没有它会怎样

17.4 阅读时最值得记录的东西

  1. 关键数据结构
  2. 关键流程函数
  3. 阶段划分
  4. 面试表达模板

17.5 最后给你的建议

学源码最怕陷入“细节海洋”。

真正高效的方式是:

  1. 先拿下概念主线
  2. 再记住几个关键流程
  3. 最后再把源码实现细节往主线里挂

你只要能稳定讲清这 5 个点,React 原理面试基本就稳了一大半:

  1. Fiber 为什么出现
  2. render/commit 为什么分阶段
  3. Diff 为什么只比较同层
  4. Hook 为什么靠顺序
  5. React 18 并发更新到底是什么