React 的渲染时机
React 通过 组件的 生命周期 和 状态更新 来决定何时 渲染 或 重新渲染 UI。React 会在以下几种情况触发渲染:
1 首次渲染
当你首次渲染一个 React 组件时,React 会:
- 调用 组件的
render()方法(对于类组件),或者 直接 执行函数组件; - 返回 一个 React 元素,描述 要渲染的 UI;
- 然后,React 会将这个 React 元素 转化为 真实的 DOM 元素,并将其显示在 浏览器中。
function Greeting(props) {
return <h1>Hello, {props.name}!</h1>; // 返回一个 React 元素
}
- 你写
<Greeting name="Alice" />,这是一个 React 元素的描述; - React 执行 Greeting 组件的 函数体;
- 返回一个 React 元素(比如
<h1>Hello, Alice!</h1>); - React 会通过 虚拟 DOM 更新 实际的 浏览器 DOM,显示
<h1>Hello, Alice!</h1>。
2 当 props 或 state 发生变化时
React 会在 组件的 props 或 state 改变时 触发 重新渲染。这意味着,如果组件的 props 或 state 更新,React 会 重新计算 组件的 UI(即 调用 render() 或 执行 函数组件),并根据 新的数据 更新 DOM。
props改变:父组件 的props变化会导致 子组件 重新渲染;state改变:组件内部 的state变化会导致 该组件 重新渲染。
props 更新
function Parent() {
const [name, setName] = useState("Alice");
return (
<div>
<Greeting name={name} />
<button onClick={() => setName("Bob")}>Change Name</button>
</div>
);
}
在这个例子中,当点击按钮时,name 状态变化,Greeting 组件的 props 也会 发生变化,React 会 触发 Greeting 组件 重新渲染。
state 更新
function Greeting(props) {
const [count, setCount] = useState(0);
return (
<div>
<h1>Hello, {props.name}!</h1>
<p>You've clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
);
}
在这个例子中,每次点击按钮时,count 会变化,导致 Greeting 组件 重新渲染 并显示 新的计数。
3 forceUpdate 手动触发渲染
如果你想 强制组件 重新渲染,可以使用 类组件 中的 forceUpdate() 方法。尽管这 不推荐 在实际应用中 使用,但它提供了手动触发渲染的能力。
4 React 渲染的优化
React 使用虚拟 DOM 来提高渲染性能。即使组件的 props 或 state 改变,React 也不会立即更新 DOM,而是:
- 先在 内存中 创建 一个 虚拟 DOM 树,计算出 变更;
- 与之前的 虚拟 DOM 树 进行对比,计算出 最小差异;
- 只更新 实际发生变化 的部分,这样就避免了 不必要的渲染,提高性能。