我目前是如何理解 React 中的渲染(我的改进的思维模型)
Source: Dev.to
(请提供需要翻译的正文内容,我将为您翻译成简体中文。)
组件和组件实例
首先,我们创建一个 React 组件。组件本质上是一个 JavaScript 函数。单独来看,它对浏览器屏幕没有任何影响——仅仅定义组件是看不见任何东西的。
当我们在 JSX 中使用该组件时,React 会创建一个 组件实例。一个组件可以只有一个实例,也可以有多个实例。每个实例:
- 拥有自己的状态
- 接收自己的 props
- 拥有自己的生命周期
- 保持自己的内存
我把组件实例看作是一个活的对象。它存在于时间中,可以变化、可以更新,React 会跟踪它。
从组件实例到 React 元素
每个组件实例都会产生 React 元素。React 元素是在使用 React.createElement() 将 JSX 转换为 JavaScript 时创建的。简单来说:
- JSX 是语法
- React 元素是实际的 JavaScript 对象
每个 React 元素描述了 UI 中应该出现的内容。
React 元素树 与 虚拟 DOM
所有 React 元素共同构成一个 React 元素树。许多人也将这棵树称为 虚拟 DOM。这个虚拟 DOM 在 React 中扮演着非常重要的角色,因为它使 React 能够:
- 高效比较 UI 变化
- 避免不必要的真实 DOM 更新
- 只更新实际需要的部分
React 渲染(真正的含义)
现在让我们来谈谈渲染,这个概念常被误解。在 React 中,渲染 并不 意味着在屏幕上显示某些东西。渲染指的是 React 内部计算 UI 更改的过程。
当渲染被触发时
渲染主要在两种情况下触发:
- 初始渲染 – 当我们打开网站,UI 第一次出现时。
- 状态更新渲染 – 当组件内部的任意状态被更新时。
整个过程发生在 React 中,而不是在浏览器中。
在渲染期间会发生什么
我们已经拥有一个 Virtual DOM 树。当状态更新发生时:
- React 不会盲目地重建所有内容。
- React 会从状态被更新的节点开始重新渲染该部分树。
- 只有受影响的组件及其子组件会被重新渲染;父组件不会被不必要地重新渲染。
随后,React 会将 previous tree 与 newly created tree 进行比较。这个比较过程称为 reconciliation。
Fiber 和 Fiber 树(重要部分)
调和由 React 的内部引擎 Fiber 处理。Fiber 拥有自己的结构,称为 Fiber 树。关于 Fiber 树的关键点:
- 它只会创建一次。
- 不会一次又一次地重新创建。
- 它会随着时间不断更新。
Fiber 树的外观与 Virtual DOM 树不同,但它以更优化的方式表示相同的 UI。
Work‑In‑Progress Fiber Tree
当更新发生时:
- React 会创建一个 Work‑In‑Progress Fiber Tree。
- 更改会被应用到这棵新树上。
- React 在后台准备所有内容。
一旦工作完成,Work‑In‑Progress 树就会成为当前的 Fiber 树。
提交阶段
在调和完成后,React 进入 提交阶段。在此阶段:
- 更改被应用到真实的 DOM。
- 更新变得可见。
整个过程同步进行,对开发者是隐藏的。
浏览器渲染(React 完成后)
在 React 完成工作后,浏览器接管控制。浏览器决定布局、绘制以及屏幕上事物的外观。这称为 browser paint,它不是 React 的责任。
完整流程(据我理解)
Component creation
→ Component instance
→ React elements
→ React element tree (Virtual DOM)
→ Rendering trigger
→ Re‑rendering
→ Reconciliation (Fiber)
→ Work‑In‑Progress Fiber Tree
→ Commit phase
→ Browser paint
最后思考
我认为这个解释比我之前的理解要好得多。对我而言,最重要的领悟是 React 渲染是关于重新计算 UI,而不是直接更新屏幕。
我仍在学习中,但这个思维模型感觉扎实且实用,它帮助我理解:
- 为什么会发生重新渲染
- React 如何保持高速
- 更新实际上是如何到达屏幕的
这就是我目前的理解——我相信随着深入学习,它会不断演进。