React.memo详解

16 阅读2分钟

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>
  )
}
  • 只要 onButtonClickdata 的引用都未变,ExpensiveComponent 就不会重新渲染,即使父组件本身在更新。

注意事项

  • 默认是浅比较,复杂对象或函数类型的 props 需要配合 useMemo/useCallback 保持引用稳定,否则 memo 失效。
  • React.memo 只对 props 变化敏感,组件内部的 state 或 context 变化仍然会导致组件重新渲染
  • 不要滥用,只有在性能瓶颈或组件渲染开销较大时才建议使用。

总结

**React.memo 是函数组件的性能优化工具,通过缓存组件的渲染结果,只有在 props 发生变化时才重新渲染,从而避免无效的渲染操作。