React.memo 的使用
什么是 React.memo?
React.memo
是 React 的高阶组件(HOC),用于优化函数式组件的性能。它通过“浅比较”来判断组件的 props 是否发生变化,如果没有变化,就跳过重新渲染,从而提高性能。
语法
const MemoizedComponent = React.memo(Component);
-
Component
:原始的函数组件。 - 返回值是一个增强版的组件,它具有相同的功能,但添加了性能优化。
使用场景
-
组件性能优化:
- 适用于 props 很少变化的组件。
- 避免不必要的重新渲染。
-
父组件更新时,子组件无需更新:
- 如果子组件的 props 未变化,
React.memo
会阻止子组件的更新。
- 如果子组件的 props 未变化,
示例代码
简单示例
import React from 'react';
// 普通函数组件
const MyComponent = ({ value }) => {
console.log("MyComponent rendered");
return <div>{value}</div>;
};
// 使用 React.memo
const MemoizedComponent = React.memo(MyComponent);
export default function App() {
const [count, setCount] = React.useState(0);
return (
<div>
<button onClick={() => setCount(count + 1)}>Increment Count</button>
{/* 即使 count 变化,MemoizedComponent 不会重新渲染 */}
<MemoizedComponent value="Hello, World!" />
</div>
);
}
输出行为:
- 点击按钮时,
MyComponent
不会重新渲染,因为它的value
prop 没有变化。
带自定义比较函数
默认情况下,React.memo
使用 浅比较(Object.is
)比较 props。如果组件有复杂 props(如对象、数组等),可以通过提供自定义比较函数来控制比较逻辑。
语法
React.memo(Component, areEqual);
-
areEqual(prevProps, nextProps)
:一个返回布尔值的函数。-
true
:跳过重新渲染。 -
false
:触发重新渲染。
-
示例
const MyComponent = ({ user }) => {
console.log("MyComponent rendered");
return <div>{user.name}</div>;
};
// 自定义比较函数
const areEqual = (prevProps, nextProps) => {
return prevProps.user.name === nextProps.user.name;
};
// 使用自定义比较函数
const MemoizedComponent = React.memo(MyComponent, areEqual);
export default function App() {
const [user, setUser] = React.useState({ name: "John" });
return (
<div>
<button
onClick={() => setUser({ name: "John" })} // 更新引用,但值没变
>
Update User
</button>
<MemoizedComponent user={user} />
</div>
);
}
输出行为:
- 点击按钮时,
MyComponent
不会重新渲染,因为自定义比较函数判定user.name
未变化。
React.memo vs React.PureComponent
特性 | React.memo | React.PureComponent |
---|---|---|
适用范围 | 函数组件 | 类组件 |
比较逻辑 | 可提供自定义比较函数 | 内置浅比较(shouldComponentUpdate ) |
灵活性 | 更灵活,需要手动配置 | 自动配置 |
注意事项
-
浅比较的局限性:
- 如果 props 是复杂的对象或数组,浅比较可能导致错误的判断,需要使用自定义比较函数。
- 如需深度比较,可能会引入额外的性能开销。
-
滥用可能适得其反:
- 如果组件很简单或更新频率很低,
React.memo
的比较逻辑可能会增加性能开销。
- 如果组件很简单或更新频率很低,
-
适用于无副作用的纯函数组件:
- 如果组件依赖外部变量或包含副作用,
React.memo
可能无法正确优化。
- 如果组件依赖外部变量或包含副作用,
总结
React.memo
是优化函数组件性能的有效工具,适用于 props 不经常变化的场景。但需要谨慎使用,避免因为错误的比较逻辑或过度优化而增加复杂性。