react 如何渲染的
React 渲染机制
React 的渲染过程分为两个主要阶段:协调(Reconciliation)和提交(Commit)。协调阶段负责计算差异(Diffing),提交阶段将变化应用到 DOM。
虚拟 DOM 的作用
React 使用虚拟 DOM 作为中间层,通过对比新旧虚拟 DOM 树的差异,最小化直接操作真实 DOM 的开销。虚拟 DOM 是一个轻量级的 JavaScript 对象,描述 UI 的结构和状态。
协调阶段的流程
-
生成虚拟 DOM 树
组件通过render方法或函数组件的返回值生成虚拟 DOM 树。每次状态或属性变化时,会重新生成新的虚拟 DOM 树。 -
Diffing 算法
React 通过启发式算法(如按层级比较、Key 优化)对比新旧虚拟 DOM 树,找出需要更新的部分。算法的时间复杂度为 O(n)。- 元素类型不同:直接销毁旧子树,创建新子树。
- 元素类型相同:递归比较子节点。
- Key 属性:帮助 React 识别列表中元素的移动或重用。
提交阶段的流程
-
更新 DOM
根据协调阶段的结果,React 调用ReactDOM或其他渲染器(如 React Native)的 API,将差异应用到真实 DOM。此阶段可能触发浏览器重绘或重排。
-
生命周期与副作用
在提交阶段后,React 触发相关生命周期方法(如componentDidMount、componentDidUpdate)或 Hook 的副作用(如useEffect)。
性能优化策略
-
避免不必要的渲染
使用React.memo或shouldComponentUpdate跳过无变化的组件渲染。 -
稳定的 Key
列表渲染时使用唯一且稳定的 Key,避免因 Key 变化导致不必要的 DOM 操作。
-
批量更新
React 自动批量处理状态更新,减少渲染次数。异步场景可使用ReactDOM.unstable_batchedUpdates(非正式 API)。
示例代码
function MyComponent({ data }) {
// 生成虚拟 DOM
return (
<div>
{data.map(item => (
<ChildComponent key={item.id} item={item} />
))}
</div>
);
}
// 优化:跳过 props 未变化的渲染
const ChildComponent = React.memo(({ item }) => {
return <div>{item.name}</div>;
});
公式说明
虚拟 DOM 的 Diffing 算法核心逻辑可简化为:
$$ \text{Diff}(V{\text{old}}, V{\text{new}}) = \text{PatchList} $$
其中:
- $V_{\text{old}}$ 是旧虚拟 DOM 树。
- $V_{\text{new}}$ 是新虚拟 DOM 树。
- $\text{PatchList}$ 是应用到真实 DOM 的最小操作集合。






