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

为何useCallback在依赖windowSize未更新时仍触发?

问题原因与解决方案

核心误解

你对useCallback的作用理解有误:useCallback的本质是缓存函数的引用,保证只有当依赖项变化时,才会生成新的函数实例。但它并不会限制函数的调用时机——只要代码里执行了这个函数(比如你这里的calculateColumnCount(containerWidth)),不管依赖有没有变,函数都会被触发执行。

你的代码问题

当searchValue变化时,组件重新渲染,此时代码会执行const columnCount = numColumns ?? calculateColumnCount(containerWidth),这里直接调用了calculateColumnCount函数,所以console.log('CALLBACK FUNC')会触发,和useCallback的依赖无关。

解决方案

如果你想让calculateColumnCount的执行结果只在windowSize(或相关依赖)变化时才重新计算,需要用useMemo来缓存计算结果,而不是只缓存函数引用:

const [searchValue, setSearchValue] = useState<string>('');

useEffect(() => {
  gridRef.current?.recomputeGridSize();
  console.log('TRIGGER WINDOW SIZE')
}, [windowSize]);

const calculateColumnCount = useCallback((width: number) => {
  console.log('CALLBACK FUNC')
  return Math.floor(width / itemMinWidth);
}, [windowSize, itemMinWidth]) // 注意:如果itemMinWidth是外部变量/状态,必须加入依赖

// 用useMemo缓存计算结果,只有依赖变化时才重新调用函数
const columnCount = useMemo(() => {
  return numColumns ?? calculateColumnCount(containerWidth);
}, [numColumns, calculateColumnCount, containerWidth]);

这样,只有当numColumns、calculateColumnCount(即windowSize变化时)或containerWidth变化时,才会重新调用calculateColumnCount并更新columnCount,searchValue变化时不会触发函数执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 11:19:56