为什么不通过在React(useEffect)中使用清除功能来清除setTimeOut?

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

我想在卸载组件时清除所有setTimeOut。即使我已经将clearTimeOut用作清理函数,但错误仍然存​​在:“警告:无法在已卸载的组件上执行React状态更新。这是空操作,但是它表明内存泄漏要修复,请在useEffect清除功能中修复并取消所有订阅和异步任务“

useEffect(() => {
     const timeOut = {timeout1: ()=>setTimeout(() => setProgress((preV) => preV + 15), [
        550,
      ]),timeout2 : ()=> setTimeout(() => setMessage("All most done"), [500])}
      timeOut.timeout1();
      timeOut.timeout2();


    return () => {
      clearTimeout(timeOut.timeout1);
      clearTimeout(timeOut.timeout2);
    };
  }, [progress,message]);

有人知道如何解决此问题吗?任何帮助,将不胜感激!

reactjs settimeout use-effect
2个回答
1
投票

timeout1不存储setTimeout的返回值,该值是timerId,而是存储执行超时的函数的引用

您可以编写代码,使其立即使用Immediately invoked functions执行超时,以便timeout1timeout2具有timerIds

useEffect(() => {
     const timeOut = {
           timeout1: (()=>setTimeout(() => setProgress((preV) => preV + 15), 550))(),
           timeout2 : (()=> setTimeout(() => setMessage("All most done"), 500))()
     }



    return () => {
      clearTimeout(timeOut.timeout1);
      clearTimeout(timeOut.timeout2);
    };
  }, [progress,message]);

但是您可以简单地运行超时而无需将其写为IIFE

useEffect(() => {
     const timeOut = {
           timeout1: setTimeout(() => setProgress((preV) => preV + 15), 550),
           timeout2 : ()=> setTimeout(() => setMessage("All most done"), 500)
     }



    return () => {
      clearTimeout(timeOut.timeout1);
      clearTimeout(timeOut.timeout2);
    };
  }, [progress,message]);

0
投票

如何使用局部变量来跟踪组件是否已安装。

useEffect(() => {
  let run = true;

  const timeOut = {
    timeout1: () => setTimeout(() => setProgress((preV) => preV + 15), [550]),
    timeout2: () => setTimeout(() => setMessage('All most done'), [500]),
  };

  if (run) {
    timeOut.timeout1();
    timeOut.timeout2();
  }

  return () => {
    clearTimeout(timeOut.timeout1);
    clearTimeout(timeOut.timeout2);
    run = false;
  };
}, [progress, message]);
© www.soinside.com 2019 - 2024. All rights reserved.