You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

未使用useCallback时,React.memo为何无法阻止组件重渲染?

问题解析:React.memo为何无法阻止组件重渲染

示例代码

function App(){
  const [count,setCount]=useState(0);

  function countUp(){
    setCount(count=>count+1);
  }
  function countDown(){
    setCount(count=>count-1);
  }

  return(
    <div>
      <p>count:{count}</p>
      <AppTwo countUp={countUp} countDown={countDown}/>
    </div>
  )  
}

const AppTwo=React.memo(({countUp, countDown})=>{
  useEffect(()=>{
    console.log('re-rendering.')
  })

  return(
    <div>
      <button onClick={countUp}>count UP</button>
      <button onClick={countDown}>count DOWN</button>
    </div>
  )
})

核心原因

这本质是JavaScript中函数的引用特性导致的:

  • 在JavaScript里,函数属于引用类型,每次创建新函数(比如App组件每次渲染时定义的countUp、countDown),都会在内存中生成全新的引用地址。
  • React.memo默认采用浅比较判断组件是否需要重渲染:对比前后两次props时,会检查每个prop的引用是否一致。
  • 每次App组件因count变化重渲染时,都会重新创建countUp和countDown函数,新函数的引用和上一次完全不同。React.memo发现props里的函数引用变了,就会判定“props发生变化”,进而触发AppTwo的重渲染。

解决办法

用useCallback钩子缓存函数引用:

function App(){
  const [count,setCount]=useState(0);

  // 用useCallback缓存函数,依赖项为空(因为函数内部用了函数式更新,不依赖外部count)
  const countUp = useCallback(() => {
    setCount(count=>count+1);
  }, []);
  
  const countDown = useCallback(() => {
    setCount(count=>count-1);
  }, []);

  return(
    <div>
      <p>count:{count}</p>
      <AppTwo countUp={countUp} countDown={countDown}/>
    </div>
  )  
}

只要useCallback的依赖数组不变,每次App渲染时都会返回同一个函数引用,React.memo对比props时会认为函数没变化,就能成功阻止AppTwo的不必要重渲染。

内容的提问来源于stack exchange,提问作者Sein kim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 11:32:37