组件何时在 React 中重新渲染?
Source: Dev.to

什么会触发重新渲染?
当组件使用 useState 更改状态时,React 会调度对该组件的重新渲染。
const [count, setCount] = useState(0);
const increment = () => setCount(count + 1);
属性变化
如果组件收到新的属性(即父组件重新渲染并传递新值),子组件默认也会重新渲染。即使是浅相等但引用不同的值也会触发重新渲染。
上下文变化
React Context 为在组件树中共享值提供了方式。对上下文值的任何更新都会重新渲染所有使用该上下文的组件。
父组件重新渲染
即使子组件的属性没有变化,只要父组件重新渲染,子组件也会重新渲染,除非使用 React.memo 进行记忆化。
React 协调:React 如何决定重新渲染
React 使用引用相等性(===)来比较属性和状态。如果有变化——新的对象、数组或原始值——它会假设 UI 可能需要更新。这就是为什么不可变模式至关重要;在不改变引用的情况下修改对象会导致错误或跳过渲染。
如何防止不必要的重新渲染
对纯函数组件使用 React.memo
const MyComponent = React.memo(({ name }) => {
console.log("Rendered!");
return {name};
});
使用 useCallback 和 useMemo 稳定函数和数值
如果不使用 useCallback,函数会在每次渲染时重新创建,可能导致子组件不必要的重新渲染。
const handleClick = useCallback(() => {
// Do something
}, []);
避免在属性中使用内联对象和数组
// Causes re-render
// Use useMemo
const data = useMemo(() => ({ a: 1 }), []);
尽可能保持状态局部
将状态提升或在全局上下文中存储过多会导致不必要的全树重新渲染。将状态保持在使用它的地方附近。
结论
理解 React 何时重新渲染组件对于构建高性能且可预测的界面至关重要。状态、属性、上下文和父组件更新是主要原因。通过采用不可变模式并使用 React.memo、useCallback、useMemo 等工具,你可以显著减少不必要的渲染,提高应用的响应性。