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

useMemo与防抖函数的依赖数组问题及代码优化咨询

问题原因分析
  • 第一个错误根源:getDimensions是组件每次渲染时都会重新创建的新函数,将其作为useMemo的依赖,会导致useMemo每次渲染都重新执行——相当于防抖函数失效,每次都会生成新的防抖实例,根本起不到防抖作用。
  • 第二个错误根源:React Hooks的规则明确要求useMemo必须传递依赖数组,要么传空数组(表示仅执行一次),要么传实际依赖的变量,不传则触发告警。
无告警优化方案

下面提供两种可行的优化方案,同时修复原代码中useEffect未清理监听的内存泄漏问题:

方案一:将getDimensions移入useMemo回调

直接在useMemo内部定义getDimensions,避免将其作为外部依赖,同时保证防抖函数仅创建一次:

// Get Dimensions
// Capture dimensions when `App` first mounts, immediately
// Listen for resize events and trigger 'getDimensions' (debounced)
const handleResize = useMemo(() => {
  const getDimensions = () => dispatch(setDimensions({
    viewportWidth: window.innerWidth,
    viewportHeight: window.innerHeight
  }));
  return debounce(getDimensions, 250);
}, [dispatch]) // dispatch来自useDispatch,引用稳定,不会随渲染变化

useEffect(() => {
  handleResize();
  window.addEventListener('resize', handleResize);
  
  // 清理监听与防抖队列,避免内存泄漏
  return () => {
    window.removeEventListener('resize', handleResize);
    handleResize.cancel();
  };
}, [handleResize]) // 依赖防抖函数实例,仅在实例变化时重新绑定

方案二:用useCallback包裹getDimensions

通过useCallback让getDimensions的引用保持稳定,作为useMemo的依赖时不会触发不必要的重执行:

// Get Dimensions
// Capture dimensions when `App` first mounts, immediately
// Listen for resize events and trigger 'getDimensions' (debounced)
const getDimensions = useCallback(() => dispatch(setDimensions({
  viewportWidth: window.innerWidth,
  viewportHeight: window.innerHeight
})), [dispatch]) // 依赖稳定的dispatch,保证函数引用不变

const handleResize = useMemo(() =>
  debounce(getDimensions, 250)
, [getDimensions]) // 现在getDimensions引用稳定,useMemo仅执行一次

useEffect(() => {
  handleResize();
  window.addEventListener('resize', handleResize);
  
  return () => {
    window.removeEventListener('resize', handleResize);
    handleResize.cancel();
  };
}, [handleResize])
额外说明

原代码中的useEffect未添加依赖数组和清理函数,会导致每次渲染都重复绑定resize事件,还会造成内存泄漏,上述方案已同步修复该问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 21:05:32