前言:如何读这本书,如何调试 React 源码
这本书要做的,是用一张图讲清 React 的内部机制,再带着你到源码里验证这张图。
它面向"会写 React、但没看过源码"的开发者。你不需要是内核专家,只需要:会写几行 JSX、装过 Node.js、愿意打开一个编辑器。
这本书在讲什么
React 的源码读起来难,难在没有地图。十几个包、几万行代码、递归里套递归,你不知道自己站在哪。
所以全书先给你一张地图:
这就是 React 的全部故事:一个工作循环(render + commit),一棵 Fiber 树,一组优先级。
- render 阶段:算出"界面应该长什么样"(新的 Fiber 树),可中断。
- commit 阶段:把"样子"变成现实(操作 DOM、执行 effect),不可中断。
- Scheduler + Lane:决定"什么时候算、先算谁"。
全书第一~第五部分就围绕这张图展开;第六、七部分讲 19 的并发特性与 RSC 怎么在这张图之上生长。
三种读者路径
| 你的情况 | 建议路径 |
|---|---|
| 只是想搞懂"React 到底怎么工作的" | 读第 1~5 章(Fiber 与工作循环),跳过细节章节 |
| 平时被 Hooks 的坑烦透了 | 直接跳到第三部分(Hooks),随时回翻第二部分的 diff 章节 |
| 想成为"能改源码的人" | 全部按顺序读,每章末尾的「动手实验」别跳过 |
源码在哪里:固定版本
本书分析的源码来自 React 官方仓库(facebook/react),全文锁定 v19.2.x(以 v19.2.7 为基准)。所有章节里的 <Src> 链接都指向这个版本。
两个读源码的入口:
-
monorepo 源码(本书主线):克隆仓库,切到对应 tag。
git clone https://github.com/facebook/react.gitcd reactgit checkout v19.2.7关键代码都在
packages/下。下面这份包地图是本书反复引用的坐标:包 干什么 后面重点看哪章 react对外 API、Hooks 的入口 第三部分 react-reconciler核心:Fiber、工作循环、diff 第一、二、五部分 react-dom浏览器渲染器、FiberRoot 第一、四部分 react-dom-bindingsDOM 操作、合成事件 第四部分 scheduler任务调度、时间切片 第 5、23 章 react-server/react-clientRSC 的服务端/客户端运行时 第 30 章 -
development bundle(快速验证):任何 React 19 项目里都有现成的开发版源码,
node_modules/react/cjs/react.development.js,适合随手查证某个 API 的行为。缺点是没有类型和源码注释,只适合"瞄一眼"。
调试源码的三种手段
手段 A:直接读 monorepo 源码(推荐主线)
不需要构建。packages/react-reconciler/src/ 下的文件名就是地图,比如工作循环主文件 react-reconciler/src/ReactFiberWorkLoop.js、beginWork 入口 react-reconciler/src/ReactFiberBeginWork.js。本书所有章节都按这个目录组织,源码位置统一用 <Src> 标注(点开即跳转 React v19.2.7 对应文件与行)。
手段 B:在 demo 里打断点
写一个最小 demo,用 monorepo 构建出的开发版包替换 node_modules 里的 react。构建命令以 React 官方贡献指南为准(版本不同命令略有差异),构建产物在 build/node_modules/。然后就能在浏览器里对着 beginWork 打断点、看调用栈。
本书不要求你每次阅读都构建源码,大部分章节"只读源码 + 跑跑 demo"就够。手段 B 是当你卡在一个具体行为时用的"手术刀"。
手段 C:React DevTools
DevTools 能让你在页面上直接看到真实的 Fiber 树:选中一个 DOM 节点,右侧面板显示它的 props 与内部结构。这是"把书里的图搬到眼前"最直接的方式——看到树长什么样,再回来看源码就顺了。
阅读约定
<Src>引用:形如react-reconciler/src/ReactFiberWorkLoop.js:1700的可点击链接,指向 Reactv19.2.7源码的对应文件与行。正文里会频繁出现,点开即可对照。- 代码块:带
// →注释的是"这行是关键",建议跟读;其余可跳读。 - 图例:所有图都是 Mermaid 手绘风(马卡龙配色)。语义靠形状区分:
[]矩形 = 节点/状态,{}菱形 = 判断分支,()圆角 = 入口/出口,(( ))圆 = 事件/触发;淡紫连线 = 更新主路径。 - 选讲章节:正文标注"选讲"的章节,与主线索弱相关,赶时间可跳过。
动手:跑一个最小 demo
整本书讲的工作循环,都可以回到这个最小例子来验证。点下面的按钮试试,这就是 useState 的现场:
function LiveCounter() { const [count, setCount] = useState(0); return <button onClick={() => setCount((c) => c + 1)}>点了 {count} 次</button>; }
你每点一次按钮,React 就走完一遍「render → commit」的工作循环——这正是第一部分要图解的东西。
准备好了就翻开第一部分吧。我们从一个 createRoot() 开始。