首页 > 解决方案 > 为什么在 clearTimeout 之后 SetTimeout 代码仍然执行

问题描述

我的反应组件中有以下代码:

//some code
var timeout = null; //global variable

//some more code

useEffect(() => {
    if(...some condition) {
        console.log('test1');
        timeout = setTimeout(() => {
                console.log('test2');
        }, 15 * 1000);
    } else {
        console.log('test3');
        clearTimeout(timeout);
    }
}, [some other condition]);

我在控制台中得到的输出:

test1
test3
test2 //after 15 seconds

因此,如果在此期间未清除超时,我正在尝试启动将记录“test2”的超时。正如我们所见,记录了“test3”,这意味着超时已被清除,但 15 秒后仍然记录了“test2”。这里有什么问题?

标签: javascriptreactjs

解决方案


您需要ref像这样保存超时,每次组件重新呈现时都会有一个新的超时实例,这就是为什么当clearTimeout它不起作用时,因为它清除了错误的计时器:

  const timeout = useRef(null); //global variable
  const [test, setTest] = useState(true);

  //some more code

  setTimeout(() => {
    console.log("setting");
    setTest(false);
  }, 2000);
  useEffect(() => {
    if (test) {
      console.log("test1");
      timeout.current = setTimeout(() => {
        console.log("test2");
      }, 5 * 1000);
    } else {
      console.log("test3");
      clearTimeout(timeout.current);
    }
   return () => clearTimeout(timeout.current) // clearing on unmount
  }, [test]);

上面的代码输出如下:

test1 

setting 

test3 

setting 

你可以在这里试试:https ://codesandbox.io/s/boring-waterfall-6f6iv?file=/src/App.js


推荐阅读