React 源码宏观包结构
基础包结构
react
react 基础包,只提供定义 react 组件 (ReactElement) 的必要函数,一般来说是需要和渲染器 (react-dom, react-native) 一同配合使用,在编写 react 应用的代码时,大部分都是调用此包的 api。
注意:上边所说的渲染器 (
react-dom,react-native) 其实本质上就是宿主环境,因为 React 这个框架的使用是需要配合不同的宿主环境。react-dom表示宿主环境为浏览器;react-native表示宿主环境为应用端。
react-dom
React 的渲染器之一,是 React 和 Web 平台连接的桥梁,将 react-reconciler 中的运行结果输出到 Web 页面。在编写 React 应用的代码时,大多数场景下,可以用到此包的就是一个入口函数 ReactDOM.render(<App />, document.getElementById('root')),其余使用的 api,基本上是 react 包提供的。
react-reconciler
React 得以运行的核心包 (综合协调 react-dom, react, scheduler 各个包之间的调用和配合)。管理 React 应用状态的输入和结果的输出。将输入信号最终转化成信号输出给渲染器。
scheduleUpdateOnFiber函数接收输入。- 将
fiber树生成逻辑封装到一个回调函数performSyncWorkOnRoot或performConcurrentWorkOnRoot。这其中涉及fiber树形结构,fiber.updateQueue队列,调和算法等。 - 把
performSyncWorkOnRoot或performConcurrentWorkOnRoot送入scheduler进行调度。 - 调度器
scheduler会控制回调函数执行的时机,回调函数执行完成后得到全新的fiber树。 - 再调用渲染器,形如 (
react-dom,react-native等),将fiber树形结构最终反映到界面上。
scheduler
调度机制的核心实现,控制由 react-reconciler 送入的回调函数 (这里指代 performSyncWorkOnRoot 或 performConcurrentWorkOnRoot) 的执行时机,在 concurrent 模式下可以实现任务分片。在编写 React 应用的代码时,几乎不会直接使用到此包提供的 api。
宏观总览
架构分层
为了便于理解,可以将 React 应用整体架构分为接口层 (api) 和内核层 (core) 2 个部分。
-
接口层 (api) :
react包,平时在开发过程中使用的绝大部分的 api 都是来自于此包。在 React 启动之后,正常可以改变渲染的基本操作有三个:ClassComponent中使用setState()FunctionComponent中使用 Hook,并发起dispatchAction()改变 Hook 实例对象。- 改变
context,实际上也是需要setState()或者dispatchAction()的辅助才能改变。
以上的
setState和dispatchAction都是由react包直接暴露。所以一般开发者都是直接调用react包的 api 和其他 core 包进行交互。 -
内核层 (core) :内核层由 3 个部分构成
-
调度器 (
scheduler包):核心职责只有 1 个,就是执行回调。- 把
react-reconciler提供的回调函数 (这里指代performSyncWorkOnRoot或performConcurrentWorkOnRoot函数) 包装成一个任务对象中,并丢进调度器scheduler其内部的任务队列中。 - 调度器
scheduler在内部维护一个任务队列,优先级高的排在最前面。 - 循环消费任务队列,直到任务队列清空。
- 把
-
协调器 (
react-reconciler包):核心职责有 3 个。- 装填渲染器,渲染器必须实现
HostConfig协议,每个渲染器 (如:react-dom和react-native) 都拥有不同的HostConfig协议。保证在需要的时候,能够正确调用渲染器的 api,生成实际节点 (如:DOM 节点)。 - 接收
react-dom包 (初次render) 和react包 (后续更新setState或dispatchAction) 发起的更新请求。 - 将
fiber树的构造过程包装在一个回调函数 (这里指代performSyncWorkOnRoot或performConcurrentWorkOnRoot函数),并将此回调函数传入到scheduler包等待调度。
- 装填渲染器,渲染器必须实现
-
渲染器 (
react-dom包):核心职责有 2 个。- 引导 React 应用的启动 (通过
ReactDOM.render()函数)。 - 实现
HostConfig协议,能够将react-reconciler包构造出来的fiber树表现出来,生成 DOM 节点 (宿主环境为浏览器),或者生成字符串 (服务端渲染SSR)。
- 引导 React 应用的启动 (通过
-