什么是 React.memo
React.memo 是 React 提供的一个高阶组件(HOC),它能够缓存组件的渲染结果,避免不必要的重渲染。当组件的 props 没有发生变化时,React.memo 会直接复用之前的渲染结果,从而提高应用性能。
工作原理
React.memo 通过对组件的前后两次 props 进行浅比较(shallow comparison)来决定是否需要重新渲染:
- 如果 props 没有变化,则复用缓存的组件实例
- 如果 props 发生变化,则重新渲染组件 浅比较只会比较基本类型的值是否相等,对于引用类型则只会比较引用地址是否相同
使用场景
- 纯展示组件 :当组件仅依赖 props 进行渲染,且 props 变化不频繁时
- 重渲染组件 :当组件渲染成本较高(如包含复杂计算或大量 DOM 节点)
- 列表项组件 :在长列表中使用可显著提升性能
项目实战:Button 组件优化
Button 组件通过 React.memo 进行了优化
import { useEffect, memo } from 'react';
const Button = ({ num, onClick }) => {
useEffect(() => {
console.log('button useEffect');
}, []);
console.log('Button render');
return <button onClick={onClick}>{num}Click Me</button>;
};
export default memo(Button); // 使用 memo 包装组件
与 useCallback 的协同使用
当组件接收函数作为 props 时,需要配合 useCallback 使用才能充分发挥 React.memo 的作用。在你的 App 组件中:
// 使用 useCallback 缓存函数引用
const handleClick = useCallback(() => {
console.log('handleClick');
}, [num]); // 仅当 num 变化时才重新创建函数
// 将缓存的函数传递给 memo 组件
<Button num={num} onClick={handleClick}>Click Me</Button>
注意事项
- 不要过度使用 :
- 对于简单组件,memo 的比较成本可能高于重渲染成本
- 避免对所有组件都使用 memo
- 引用类型 props 问题 :
// 错误示例:每次渲染都会创建新数组
<Button items={[1, 2, 3]} />
// 正确做法:使用 useMemo 缓存引用类型
const items = useMemo(() => [1, 2, 3], []);
<Button items={items} />
- 自定义比较函数 :可以通过第二个参数自定义比较逻辑:
const areEqual = (prevProps, nextProps) => {
// 自定义比较逻辑
return prevProps.id === nextProps.id;
};
export default memo(Button, areEqual);
React.memo vs useMemo
总结
React.memo 是优化 React 应用性能的重要工具,尤其适用于频繁重渲染的纯展示组件。通过与 useCallback 和 useMemo 配合使用,可以有效避免不必要的渲染,提升应用响应速度。但需注意避免过度优化,只有在确实遇到性能问题时才考虑使用。