为何使用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
相关产品推荐
相关产品推荐

