二、React 旧版架构
00 min
2024-9-3

React 从 v15 升级到了 v16 之后重构了整个架构。这一节我们聊聊 v15 为什么不能满足快速响应的理念,以至于被重构。
 

React15 架构


React 15架构可以分为两层:
  • Reconciler(协调器)—— 负责找出发生变化的组件
  • Renderer (渲染器)—— 负责将发生变化的组件渲染的界面中
 

Reconciler(协调器)

在 React 中可以通过 this.setState、this.forceUpdate、ReactDOM.render 等 API 触发更新。
每当有更新发生时,Reconciler 会做如下工作:
  1. 调用函数组件、或 class 组件的 render 方法,将返回的JSX 转换为虚拟 DOM
  1. 将虚拟 DOM 和上次更新时的虚拟 DOM 对比
  1. 通过对比找出本次发生变化的虚拟 DOM
  1. 通过 Renderer 将变化的虚拟 DOM 渲染到页面上
你可以在这里看到 React 官方对 Reconciler 的解释
 

Renderer(渲染器)

由于 React 支持跨平台,所以不同平台有不同的 Renderer。我们前端最熟悉的是负责在浏览器环境中渲染的 Renderer —— ReactDOM
除此之外,还有:
  • ReactNative 渲染器,渲染 App 原生组件
  • ReactTest 渲染器,渲染出纯 JS 对象用于测试
  • ReactArt 渲染器,渲染到 Canvas,SVG 或 VML (IE8)
每次更新发生时,Renderer 接收到 Reconciler 通知,将变化的组件渲染到当前的宿主环境中。
你可以在这里看到 React 官方对 Renderer 的解释。
 

React 15架构的缺点


在 Reconciler 中,mount 的组件会调用 mountComponent,update 的组件会调用 updateComponent。这两个方法都会递归更新子组件。
 
递归更新子组件的缺点
由于递归执行,所以更新一旦开始就无法中断了。当层级很深的时候,递归更新的时间就会超过 16ms ,用户交互就会卡顿。
 
在上个章节中,我们已经提到了 React 的解决办法 —— 用可中断的更新代替同步的更新。那么React15 的架构支持异步更新吗?我们可以看一个例子:
demo code
初始化时 state.count = 1,每次点击按钮 state.count++,列表中 3 个元素的值分别是 1、2、3 乘以 state.count 的结果,用红色标注了更新的步骤:
notion image
我们可以看到,Reconciler 和 Renderer 是交替工作的,当第一个 li 在页面上已经变化后,第二个 li 再进入 Reconciler。
由于整个过程都是同步执行的,所以在用户看来所有的 DOM 都是同时更新的。
接下来,我们模拟一下如果中途中断更新会怎么样?
 
注意 以下是我们模拟中断的情况,实际上 React15 并不会中断进行中的更新
 
notion image
当第一个 li 完成更新是中断更新,即步骤 3 完成后中断更新,此时后面的步骤都还没有执行。
用户原本期望得到 123 变为 246,但实际看到的却是更新不完整的 DOM!(即 223),基于这个原因,React 决定重写整个架构。
 
 
一、React 设计理念
一、React 设计理念
三、React 新版架构
三、React 新版架构
 
上一篇
空白文章
下一篇
解密 React:探究背后的原理与源码