1. React.memo
- 使用场景:用于函数式组件,对组件的props进行浅比较,如果props没有变化,React会复用上次渲染的结果,从而避免不必要的重新渲染。适用于那些纯展示型组件,且props变化频率较低的场景。
- 示例:
const MyComponent = React.memo((props) => {
return <div>{props.value}</div>;
});
- 与其他两者区别:
React.memo
作用于组件层面,比较的是props;而 useMemo
和 useCallback
作用于函数组件内部。
2. useMemo
- 使用场景:用于缓存一个值,只有当依赖项发生变化时才会重新计算该值。常用于计算成本较高的操作,比如复杂的数据处理、昂贵的函数调用等,避免在每次渲染时都进行重复计算。
- 示例:
const memoizedValue = useMemo(() => {
return expensiveCalculation(props.data);
}, [props.data]);
- 与其他两者区别:
useMemo
缓存的是一个值(通常是函数调用的返回结果),而 useCallback
缓存的是一个函数,React.memo
是对组件整体进行优化。
3. useCallback
- 使用场景:用于缓存一个函数,只有当依赖项发生变化时才会重新创建该函数。在将函数作为props传递给子组件,且子组件可能因为函数引用变化而重新渲染时非常有用,防止不必要的子组件重新渲染。
- 示例:
const handleClick = useCallback(() => {
console.log('Button clicked');
}, []);
- 与其他两者区别:它专注于缓存函数,与
useMemo
不同在于 useMemo
返回值,与 React.memo
区别在于作用层面和比较对象不同。
4. 在复杂大型React应用中的优化策略
- 结合三者:
- 对于纯展示组件,使用
React.memo
进行包裹,减少不必要的渲染。
- 在组件内部,如果有昂贵的计算,使用
useMemo
缓存计算结果。
- 当需要将函数作为props传递给子组件时,使用
useCallback
缓存函数,避免子组件不必要的重新渲染。
- 其他优化技巧:
- 虚拟列表:在处理大量数据列表展示时,使用虚拟列表技术(如
react - virtualized
或 react - window
),只渲染可见区域的列表项,提高性能。
- 代码拆分:通过
React.lazy
和 Suspense
进行代码拆分,实现按需加载组件,减少初始加载体积。
- 优化事件绑定:合理使用事件委托,减少事件处理器的数量,降低内存开销。
- Memoize状态更新:对于复杂的状态更新逻辑,可以使用类似于
immer
库,以更高效的方式处理不可变数据更新,减少重新渲染的范围。