news 2026/9/27 21:11:34

图解 React 源码系列:react-illustration-series 原理学习路线与源码导读

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
图解 React 源码系列:react-illustration-series 原理学习路线与源码导读
  • 教程
  • 前端

【免费下载链接】react-illustration-series

图解react源码, 用大量配图的方式, 致力于将react原理表述清楚.

项目地址:https://gitcode.com/gh_mirrors/re/react-illustration-series
点击查看免费下载

本文以 react-illustration-series 的系列总览文档(docs/index.md)为骨架,结合 readme.md 与docs/main、docs/algorithm、docs/interview下各篇原理文章,为读者梳理一条"从宏观包结构到微观运行机制"的 React 17 源码阅读路径。读完本文,你将掌握该仓库的内容版图、核心包职责划分、两大工作循环的主干逻辑、三种启动模式,以及如何在本机以 dumi 站点形式浏览全文。

系列定位:用配图讲清 React 原理

react-illustration-series 是一个以"图解"为核心形式的 React 源码原理系列,仓库描述明确写道:"图解 react 源码,用大量配图的方式,致力于将 react 原理表述清楚。"整个系列基于react@17.0.2展开分析,并尽可能跟随 React 版本升级持续更新;随着官方升级,主要版本的文章会保存在以版本号命名的分支中(当前仓库主分支对应 v17.x 系列,历史版本另有 v16.13.1、v17.0.1 分支)。

系列的展开主线索是react 核心包结构和运行机制,覆盖的核心内容板块包括:

  • react 宏观结构(核心包之间的依赖与调用关系)
  • react 工作循环(任务调度循环与 fiber 构造循环)
  • react 启动模式(legacy / Blocking / Concurrent)
  • react fiber 原理(树构造、对比更新、渲染提交)
  • react hook 原理(状态 Hook、副作用 Hook)
  • react 合成事件原理

仓库本身是一份以 dumi 驱动的静态文档站点(见 package.json,依赖dumi@^2.2.0),支持npm run dev在本地启动文档站逐篇阅读。

适用读者

官方在 docs/index.md 中给出了两条读者门槛,定位相当明确:

  1. 对react、react-dom开发 web 应用有实践经验;
  2. 期望深入理解react内在作用原理。

也就是说,这个系列不是入门教程,适合已经能熟练使用 React 写应用、想进一步弄清"框架内部到底怎么运行"的开发者。系列同时强调"不是面经,但会列举一些面试题来加深对 react 理解"——面试题板块独立存在于 docs/interview/index.md,后续会详细介绍。

内容版图:五大板块构成完整学习路径

综合 readme.md 与 docs/index.md 的目录组织,整个系列的内容可划分为五个板块。以下逐一给出对应文章与主题要点,所有路径均以仓库根目录为基准。

1. 基本概念(先建立宏观认知)

  • 宏观包结构:介绍 web 开发相关的 4 个核心包及架构分层;
  • 两大工作循环:任务调度循环与fiber构造循环的分工与联系;
  • 高频对象:梳理 fiber、updateQueue、task 等贯穿始终的数据对象。

2. 运行核心(主线:一次更新如何变成一次渲染)

  • reconciler 运作流程:把 reconciler 归结为"输入 → 注册调度任务 → 执行调度任务 → 输出"等步骤;
  • 启动过程:三种启动模式及三个全局对象的创建;
  • 优先级管理:React 体系中的优先级分类与转换;
  • scheduler 调度原理:任务队列、时间切片与回调时机控制;
  • fiber 树构造(基础准备)、fiber 树构造(初次创建)、fiber 树构造(对比更新):fiber 树三阶段构造细节;
  • fiber 树渲染:commit 阶段的副作用处理与 DOM 输出;
  • 异常处理(系列规划中的主题)。

3. 数据管理(状态、副作用与跨组件数据)

  • 状态与副作用:class / function 组件中改变 fiber 节点状态与副作用的 api;
  • hook 原理(概览):Hook 与 Fiber 的关系及数据结构;
  • hook 原理(状态 Hook)、hook 原理(副作用 Hook);
  • context 原理。

4. 交互(事件体系)

  • 合成事件原理:事件代理与两阶段派发机制。

5. 高频算法(阅读源码前的前置功课)

  • 位运算:fiber 的 flags、lane 等大量基于位运算的标记设计;
  • 堆排序:任务调度循环所使用的二叉堆;
  • 深度优先遍历:fiber 树构造的基本遍历方式;
  • 链表操作:fiber 链式结构、更新队列的合并;
  • 栈操作:上下文栈的入栈出栈;
  • diff 算法:reconcile 子节点的核心算法。

这五个板块在阅读顺序上存在依赖关系:建议先读"基本概念"建立全局观,再进入"运行核心"跟完整条渲染链路,随后用"数据管理"与"交互"补全组件层细节,过程中按需查阅"高频算法"作为理解工具。

核心包结构:四个包如何分工协作

宏观包结构一文指出,React 工程目录 packages 下共有 35 个包(对应@17.0.2版本),其中与web 开发相关的核心包只有 4 个,整个系列近 20 篇文章正是以这 4 个包为线索展开:

包职责定位开发者在日常编码中的接触面
react基础包,只提供定义 React 组件(ReactElement)的必要函数编写应用时调用的绝大多数 api 均来自此包
react-domReact 与 web 平台连接的桥梁(浏览器与 Node.js 环境),把 reconciler 的运行结果输出到界面上多数场景只用到入口函数ReactDOM.render(<App/>, document.getElementById('root'))
react-reconcilerReact 得以运行的核心包,综合协调react-dom、react、scheduler各包之间的调用与配合通常不会直接使用
scheduler调度机制的核心实现,控制回调函数的执行时机,concurrent 模式下可实现任务分片通常不会直接使用

其中react-reconciler与scheduler的协作链路可以这样概括:react-reconciler接受输入(scheduleUpdateOnFiber),把 fiber 树生成逻辑封装进回调函数(涉及 fiber 树形结构、fiber.updateQueue队列、调和算法等),再将回调(performSyncWorkOnRoot或performConcurrentWorkOnRoot)送入scheduler调度;scheduler控制回调执行时机,回调执行完毕后得到全新的 fiber 树;最后调用渲染器(react-dom、react-native等)把 fiber 树结构反映到界面上。

为了便于理解,该文还提出了一套**接口层(api)/ 内核层(core)**的二分视角(并注明这并非官方术语,仅为理解 react 而做的分解):

  • 接口层:react包。React 启动后能改变渲染的基本操作只有 3 种——class 组件中调用setState()、function 组件中通过 hook 发起dispatchAction改变 hook 对象、改变 context(也需要setState或dispatchAction辅助)。这些 api 均由react包直接暴露。
  • 内核层:由 3 部分构成——
    1. 调度器(scheduler包):唯一职责是执行回调。把react-reconciler提供的回调包装成任务对象,内部维护一个按优先级排列的任务队列(二叉堆),循环消费直到队列清空;
    2. 构造器(react-reconciler包):装载渲染器(渲染器必须实现HostConfig协议,如react-dom);接收react-dom初次 render 与react包后续 setState 发起的更新请求;将 fiber 树构造过程包装成回调交给scheduler等待调度;
    3. 渲染器(react-dom包):引导应用启动(ReactDOM.render),并实现HostConfig协议,把 fiber 树表现为真实 dom 节点(浏览器中)或字符串(SSR 场景)。

上图即 宏观包结构 一文中的内核关系概览:红色方块代表入口函数,绿色方块代表出口函数,包之间的调用脉络正是通过板块间的入口、出口函数连接起来的。理解了这张图,就基本掌握了 react 内核层的宏观结构,后续各章节均按此图的思路逐模块深入。

两大工作循环:React 运行的主干逻辑

两大工作循环 从概览图中提炼出 React 运行的两个大循环:

  1. 任务调度循环:源码位于scheduler包的Scheduler.js,是 react 应用得以运行的保证,负责循环调用、控制所有任务(task)的调度。它以二叉堆为数据结构(详见堆排序),循环执行堆顶任务直到堆被清空;逻辑偏向宏观,只调度 task,不关心任务具体内容(甚至可以把Scheduler包脱离 react 单独使用),具体任务就是执行回调performSyncWorkOnRoot或performConcurrentWorkOnRoot。
  2. fiber 构造循环:源码位于react-reconciler包的ReactFiberWorkLoop.js,控制 fiber 树的构造,整个过程是一个深度优先遍历(详见深度优先遍历);它以树为数据结构,逻辑偏向具体实现,只是 task 的一部分(如performSyncWorkOnRoot包含 fiber 树构造、DOM 渲染、调度检测),只负责 fiber 树构造。

两者的关系是从属关系:fiber 构造循环是任务调度循环中 task 的一部分,每个 task 都会重新构造一棵 fiber 树。两大循环的分工可总结为:大循环(任务调度循环)负责调度 task,小循环(fiber 构造循环)负责实现 task。

由此,React 运行的主干逻辑——即"输入转换为输出"的核心步骤——可概括为三步:

  1. 输入:把每一次更新(新增、删除、修改节点)视为一次"更新需求"(目的是更新 DOM 节点);
  2. 注册调度任务:react-reconciler收到更新需求后并不立即构造 fiber 树,而是去scheduler注册一个新 task,即把更新需求转换成一个 task;
  3. 执行调度任务(输出):scheduler通过任务调度循环执行 task(执行过程又回到react-reconciler包中)。其中fiber构造循环是 task 的实现环节之一,循环完成后构造出最新 fiber 树;commitRoot是 task 的实现环节之二,把最新 fiber 树渲染到页面上,task 完成。

为了获得更好的性能(如批量更新、可中断渲染),React 在这条"输入 → 输出"链路上做了大量优化,而"任务调度循环 + fiber 构造循环"的相互配合正是实现可中断渲染的基础。

三种启动模式与三个全局对象

启动过程 一文衔接 reconciler 运作流程的"输入"步骤,讲解应用的启动过程。在当前稳定版react@17.0.2源码中存在 3 种启动方式:

模式入口 api代码形式特性
legacy模式ReactDOM.render(<App />, rootNode)ReactDOM.render(<App />, document.getElementById('root'), (dom) => {});(支持回调,参数是 dom 对象)当前 React app 实际使用的方式,可能不支持 concurrent 的新功能
Blocking模式ReactDOM.createBlockingRoot(rootNode).render(<App />)先createBlockingRoot(document.getElementById('root'))创建 ReactDOMRoot 对象,再调用.render(<App />)(不支持回调)实验中,仅提供 concurrent 模式的小部分功能,作为迁移第一步
Concurrent模式ReactDOM.createRoot(rootNode).render(<App />)先createRoot(document.getElementById('root'))再.render(<App />)(不支持回调)实验中,开启所有新功能,未来计划作为 React 默认开发模式

需要特别说明的是:虽然17.0.2源码中存在createRoot与createBlockingRoot方法(自行构建时默认构建 experimental 版本),但稳定版的构建入口(packages/react-dom/index.stable.js)排除了这两个 api,所以npm i react-dom安装的17.0.2稳定版中不能使用这两个 api。要体验非 legacy 模式,需要显式安装 alpha 版本或自行构建。

无论哪种模式,React 初始化时都会创建 3 个全局对象(一经创建大多数场景不会再销毁,除非root.unmount()卸载整个应用):

  1. ReactDOM(Blocking)Root对象:属于react-dom包,暴露render、unmount方法,通过调用其render方法引导应用启动;
  2. fiberRoot对象:属于react-reconciler包,作为 reconciler 运行过程中的全局上下文,保存 fiber 构建过程中依赖的全局状态,其大部分实例变量用于存储 fiber 构造循环过程中的各种状态,react 应用内部据此控制执行逻辑;
  3. HostRootFiber对象:属于react-reconciler包,是 React 应用中第一个 Fiber 对象、Fiber 树的根节点,节点类型为HostRoot。

三个对象创建过程中的RootTag参数在三种模式下各不相同,该类型决定了整个 react 应用是否支持可中断渲染。

scheduler 调度:时间切片与任务队列

调度原理 将调度中心(scheduler包)称为"React 运行时的中枢"。其最核心的代码在SchedulerHostConfig.default.js,共导出 8 个函数,核心逻辑集中在其中:

export let requestHostCallback; // 请求及时回调: port.postMessage export let cancelHostCallback; // 取消及时回调: scheduledHostCallback = null export let requestHostTimeout; // 请求延时回调: setTimeout export let cancelHostTimeout; // 取消延时回调: cancelTimeout export let shouldYieldToHost; // 是否让出主线程(currentTime >= deadline && needsPaint) export let requestPaint; // 请求绘制: 设置 needsPaint = true export let getCurrentTime; // 获取当前时间 export let forceFrameRate; // 强制设置 yieldInterval, 从源码引用看几乎没有用到

由于 react 可在 Node.js 环境使用,这些函数在不同 JS 执行环境中实现会有差异。基于普通浏览器环境,其关键机制如下:

  • 异步回调:requestHostCallback保存回调后通过MessageChannel的port.postMessage(null)触发performWorkUntilDeadline,最终执行scheduledHostCallback。注意MessageChannel在浏览器事件循环中属于宏任务,所以调度中心永远是异步执行回调函数;
  • 时间切片:默认yieldInterval为 5ms,如果一个 task 运行超过该周期,下一个 task 执行之前会把控制权归还浏览器,让浏览器处理用户输入、UI 绘制等紧急任务(shouldYieldToHost判断currentTime >= deadline && needsPaint)。

Hook 原理与数据管理概览

在"数据管理"板块,hook 原理(概览) 指出:使用任意 Hook api,最终都是为了控制 fiber 节点上"状态相关"与"副作用(Effect)相关"的属性——状态相关包括pendingProps、memoizedProps、updateQueue、memoizedState,副作用相关包括flags、nextEffect、firstEffect、lastEffect。Hook 的数据结构定义于ReactFiberHooks.old.js,核心为:

export type Hook = {| memoizedState: any, // 当前状态 baseState: any, // 基状态 baseQueue: Update<any, any> | null, // 基队列 queue: UpdateQueue<any, any> | null, // 更新队列 next: Hook | null, // next指针 |};

连同 状态与副作用、hook 原理(状态 Hook)、hook 原理(副作用 Hook)、context 原理 四篇,共同构成理解 React 数据流在 fiber 层面的完整拼图。官方也解释了引入 Hook 的动机——组件间复用状态逻辑很难、复杂组件难以理解、class 难以理解;同时 Hook 在设计上还避免了 class 需要的额外开支(类实例创建、构造函数中绑定事件处理器等),组件树层次也更浅。

面试题板块:以题带点巩固理解

系列单独设有面试题板块(docs/interview/index.md),题目会不断扩充,每题对应一个 issue 可参与讨论,当前已列出 11 题,例如:

  1. setState 是同步还是异步?
  2. class 组件生命周期有哪些?
  3. 重复调用 setState 会发生什么?
  4. 什么是 fiber 架构?
  5. 调和算法具体干什么的?
  6. key 有什么作用,可以省略吗?
  7. useState() 如何实现数据持久化?
  8. useEffect() 会有内存泄漏吗?
  9. useEffect(function, deps)中第二个参数表示依赖项,如何实现依赖项的对比?
  10. 什么是可中断渲染?
  11. context 有什么作用?

这些题目与上述各篇原理文章一一呼应,可用于读完对应章节后的自测与复盘。

版本策略与变更要点

系列最初写作于 2020 年 6 月(当时稳定版为 v16.13.1),随着 React 官方升级,主要版本文章保存在以版本号命名的分支中。主分支当前基于react@17.0.2,历史版本分支包括 v16.13.1 与 v17.0.1。readme.md 记录了 v17 系列的版本跟踪要点:

  • v17.0.0(主版本升级):使用层面基本维持不变,源码层面有两大重大变动——重构Fiber.expirationTime并引入Fiber.lanes(react-reconciler板块);事件代理节点从 document 变成 rootNode、取消合成事件的缓存池(legacy-events被移除,改为react-dom/events)。
  • v17.0.1:相比 v17.0.0 只改动了 1 个文件,修复 ie11 兼容问题,同时提升 v8 内部执行性能。
  • v17.0.2:改动集中于Scheduler包,主干逻辑没有变动,仅涉及调度性能统计相关。

系列暂时只跟踪稳定版本变动;由于 react 仓库代码改动频繁,写作过程中伴随小版本发布时,文章中的源码链接以写作当天的最新小版本为基准。

本地阅读与运行方式

仓库是一份基于 dumi 的静态站点工程(package.json),克隆到本地后即可把整个系列作为文档站浏览:

git clone https://gitcode.com/gh_mirrors/re/react-illustration-series.git cd react-illustration-series npm install npm run dev # 启动 dumi 开发服务器 npm run build # 构建静态站点

也可直接按 Markdown 文件路径在仓库中阅读,例如从 docs/main/macro-structure.md 开始,按"基本概念 → 运行核心 → 数据管理 → 交互 → 高频算法"的顺序逐步深入。

总结

react-illustration-series 的核心价值在于:以react 核心包结构和运行机制为主线索,用大量配图把"输入更新 → 注册调度任务 → 执行回调 → 构造 fiber 树 → commit 渲染"这条主干链路讲透。建议读者先通读宏观包结构与两大工作循环建立整体认知,再结合本文梳理的内容版图逐篇深入,过程中用高频算法系列补齐数据结构基础,用面试题板块检验理解深度。正如系列使用指南所言:"真正对于技术本身,不能急于求成,需要静下心来修炼"——这份仓库正是为此准备的一份结构化、可循序渐进的学习材料。

  • 教程
  • 前端

【免费下载链接】react-illustration-series

图解react源码, 用大量配图的方式, 致力于将react原理表述清楚.

项目地址:https://gitcode.com/gh_mirrors/re/react-illustration-series
点击查看免费下载
上一篇:【亲测免费】 机器视觉-使用Halcon描述与实现
下一篇:Holo1.5-3B终极指南:如何构建下一代UI智能代理

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/27 21:11:21

太原seo推广优化避坑指南3步搞定域名服务器速查手册

太原seo推广优化避坑指南3步搞定域名服务器速查手册 域名买错,服务器配错,网站上线三天没流量?别急着骂人,先看看你的后台配置。 很多太原的老板找我们做网站,第一句话不是问价格,而是问:“我那个域名怎么解析不生效?”或者“服务器为什么老连不上?”这背后其实是 域名服务器搞不懂…

作者头像 李华
网站建设 2026/9/27 21:11:07

2026最新企业网站开发的公司怎么选?防黑挂马实战指南

2026最新企业网站开发的公司怎么选?防黑挂马实战指南 网站被黑挂马,后台密码全失效,页面跳出赌博广告,这时候你慌不慌?很多老板第一反应是删库重装,但这往往治标不治本。2026年最新的网络攻击手段已经进化到利用AI批量生成漏洞利用代码,传统防火墙几乎失效。作为在华东地区深耕十年的建站从业者,我见过太…

作者头像 李华
网站建设 2026/9/27 21:10:51

天津建站模板源码避坑指南新手入门实测

天津建站模板源码避坑指南新手入门实测 找天津建站公司,最怕的就是被忽悠花大钱买个“半成品”。很多新手入门第一反应是搜“天津建站模板源码”,结果发现报价从几千到几万不等,功能看着差不多,价格差出十倍。 别急着付钱。在天津本地做网站,尤其是企业站或商城,…

作者头像 李华
网站建设 2026/9/27 21:10:14

张家界市建设网站选哪家?备案避坑与落地实操指南

张家界市建设网站选哪家?备案避坑与落地实操指南 做网站最让人头大的,往往不是代码怎么写,而是 备案流程一头雾水 。很多张家界本地的老板在找 张家界市建设网站哪家好…

作者头像 李华
网站建设 2026/9/27 21:10:07

浙江网站建设品牌设计报价全解析:避坑指南与费用明细

浙江网站建设品牌设计报价全解析:避坑指南与费用明细 自己不会代码想做网站,但看到“浙江网站建设品牌设计”这个词就头大?别慌。很多老板以为搞个官网就是填个表单、传张图,结果找了几家杭州的供应商,报价从五千到五万不等,功能描述还模棱两可。其实, 注意事项…

作者头像 李华