React 组件在以下情况会重新渲染:
- 组件自身的状态 state 发生变化
- 父组件重新渲染(默认会连带所有子组件重新渲染)
- 组件接收的 props 发生变化
解决方法:
一、 React.memo (适用于函数组件)
工作原理:
- 对组件进行浅比较(shallow compare)props
- 只有当 props 发生变化时才重新渲染
实现方式:
const ChildComponent = React.memo(function ChildComponent(props) {
// 组件内容
});
// 或者
const ChildComponent = React.memo((props) => {
// 组件内容
});
工作流程:
- 父组件渲染 → 准备传递给子组件的 props
- React 比较新旧 props(浅比较)
- 如果 props 未变化 → 跳过子组件渲染
- 如果 props 变化 → 重新渲染子组件
适用场景:
- 纯展示型组件
- props 不经常变化的组件
- 渲染开销较大的组件
二、 useMemo (缓存计算结果)
工作原理:
- 缓存计算结果
- 只有当依赖项变化时才重新计算
实现方式:
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
工作流程:
- 组件渲染时检查依赖项
- 如果依赖项未变化 → 使用缓存值
- 如果依赖项变化 → 重新计算并缓存新值
三、 useCallback (缓存函数)
工作原理:
- 缓存函数引用
- 避免因函数引用变化导致的不必要渲染
实现方式:
const memoizedCallback = useCallback(() => {
doSomething(a, b);
}, [a, b]);
工作流程:
- 组件渲染时检查依赖项
- 如果依赖项未变化 → 返回缓存的函数引用
- 如果依赖项变化 → 创建新函数并缓存
四、shouldComponentUpdate (类组件)
工作原理:
- 通过返回 true/false 控制是否更新
实现方式:
class ChildComponent extends React.Component {
shouldComponentUpdate(nextProps, nextState) {
// 自定义比较逻辑
return nextProps.value !== this.props.value;
}
render() {
// 渲染内容
}
}
五、 正确的 props(组件间数据传递机制) 设计
优化原则:
- 避免传递不必要的 props
- 将 props 拆分为更小的独立部分
- 避免传递大型对象作为 props