React.memo 是 React 提供的一个高阶组件(Higher Order Component, HOC),用于优化函数组件的性能。它的核心作用是:只有当 props 发生变化时,组件才会重新渲染,否则会复用上一次的渲染结果,从而避免不必要的渲染,提高性能。
工作原理
- React.memo 会对组件的 props 进行浅比较(shallow comparison),只有当 props 的引用或基本类型值发生变化时才触发重新渲染。
- 如果 props 是对象、数组或函数类型,只有引用变化才算变化;内容变化但引用未变,React.memo 认为 props 没变,不会重新渲染。
- 可以通过传递自定义比较函数给 React.memo,实现更精细的 props 比较(如深比较)。
典型使用场景
- 父组件频繁更新,但子组件 props 没变时,使用 React.memo 包裹子组件,可以避免子组件无谓的重新渲染。
- 大列表、复杂子组件等场景,能显著提升性能。
用法示例
// 子组件
const ExpensiveComponent = React.memo(({ onButtonClick, data }) => {
console.log('ExpensiveComponent 重新渲染')
return (
<div>
<p>数据: {data}</p>
<button onClick={onButtonClick}>点击</button>
</div>
)
})
// 父组件
function ParentComponent() {
const [count, setCount] = useState(0)
const [data, setData] = useState('初始数据')
// 使用 useCallback 缓存函数
const handleButtonClick = useCallback(() => {
console.log('按钮被点击')
setCount(prev => prev + 1)
}, []) // 空依赖数组,函数永远不会重新创建
return (
<div>
<p>父组件 Count: {count}</p>
{/* 只有当 data 变化时,ExpensiveComponent 才会重新渲染 */}
<ExpensiveComponent
onButtonClick={handleButtonClick}
data={data}
/>
<button onClick={() => setData('新数据')}>
更新数据
</button>
</div>
)
}
- 只要
onButtonClick
和data
的引用都未变,ExpensiveComponent 就不会重新渲染,即使父组件本身在更新。
注意事项
- 默认是浅比较,复杂对象或函数类型的 props 需要配合 useMemo/useCallback 保持引用稳定,否则 memo 失效。
- React.memo 只对 props 变化敏感,组件内部的 state 或 context 变化仍然会导致组件重新渲染。
- 不要滥用,只有在性能瓶颈或组件渲染开销较大时才建议使用。
总结
**React.memo 是函数组件的性能优化工具,通过缓存组件的渲染结果,只有在 props 发生变化时才重新渲染,从而避免无效的渲染操作。