在React useEffect挂钩中清理Lodash防反跳功能

问题描述 投票:0回答:2

我正在尝试将Lodash的Debounce函数与自定义钩子一起使用,以防止窗口调整大小事件触发得太频繁。尽管该钩子可以按需工作,但我仍在努力正确清理从React useEffect钩子返回的函数。这会导致浏览器控制台中出现以下错误,以及单页应用程序中整个用户会话存在的事件侦听器。

Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.

我知道有很多方法可以滚动自定义防抖钩子,但是为了这个项目大量使用Lodash,我希望尽可能使用Debounce函数。

function getSize() {
  return {
    width: window.innerWidth,
    height: window.innerHeight,
  };
}

export default function useWindowSize(debounceDelay = 500) {
  const [windowSize, setWindowSize] = useState(getSize);

  useEffect(() => {
    function handleResize() {
      setWindowSize(getSize());
    }

    const debounced = debounce(handleResize, debounceDelay);
    window.addEventListener(`resize`, debounced);

    return () => window.removeEventListener(`resize`, debounced.cancel());
  }, [debounceDelay]);

  return windowSize;
}
javascript reactjs lodash
2个回答
0
投票

您直接调用取消功能。您应该只使用debounced,这就是您的监听器中添加的内容:

return () => {
  window.removeEventListener('resize', debounced)
}

0
投票

不需要通过debounce.cancel()。在删除事件侦听器时,您需要将相同的引用传递给创建侦听器时使用的函数]

useEffect(() => {
    function handleResize() {
      setWindowSize(getSize());
    }

    const debounced = debounce(handleResize, debounceDelay);
    window.addEventListener(`resize`, debounced);

    return () => {
         debounce.cancel()
         window.removeEventListener(`resize`, debounced); // use debounced directly
     }
  }, [debounceDelay]);
© www.soinside.com 2019 - 2024. All rights reserved.