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

为何使用useCallback与memo仍无法阻止React组件重渲染?

useCallback与memo没拦住重渲染?问题在这

问题根源在于你用useCallback缓存的函数,依赖了一个每次父组件渲染都会重新创建的对象,导致缓存失效,memo自然拦不住Shipping组件的重渲染。

看你代码里的shippingOptions,是直接定义在父组件内部的普通对象:

const shippingOptions = {
  ground: 5,
  express: 10
};

每次点击产品触发父组件重渲染(因为selectedProduct变了),这个对象都会被重新生成,引用地址跟之前不一样。而你给useCallback的依赖数组里加了shippingOptions,React一看依赖变了,就会重新生成getShippingCost函数。新函数传给Shipping组件时,memo检测到props变了,就会触发重渲染。

怎么改?

  • 要是shippingOptions是静态数据(不会跟着组件状态变),直接把它移到组件外面去,别放在组件函数里:
// 移到组件外面,永远只创建一次
const shippingOptions = {
  ground: 5,
  express: 10
};

function ProductList() {
  // ... 你的组件逻辑
}
  • 要是shippingOptions需要根据组件状态动态生成,就用useMemo把它缓存起来,保证引用地址稳定:
function ProductList() {
  const shippingOptions = useMemo(() => ({
    ground: 5,
    express: 10
  }), []); // 空依赖,只在组件初始化时生成一次

  const getShippingCost = useCallback((productId: number) => {
    return shippingOptions.ground;
  }, [shippingOptions]);

  // ... 其他逻辑
}

另外再确认下Shipping组件确实用React.memo包了,而且没传其他会频繁变化的props。这样改完,getShippingCost的引用就稳了,父组件再因产品选中状态重渲染时,Shipping组件的props没变化,memo就能成功拦住不必要的重渲染了。

内容的提问来源于stack exchange,提问作者Rajat Saxena

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 20:55:19