在哪里清除 setTimeout 反应?

where to clear setTimeout in react?

  useEffect(() => {
    const id_1 = setTimeout(() => {
      // do something
      clearTimeout(id_1);
    }, 500);
  }, [success_failure_msg[0]]);

  useEffect(() => {
    const id_1 = setTimeout(() => {
      // do something
    }, 500);
    return () => clearTimeout(id_1);
  }, [success_failure_msg[0]]);

有什么区别,正确的做法是什么?

我觉得两个都不对,cleartimeout 应该在 settimetimeout 之前 当 success_failure_msg 更改两次时,settimeout 仅触发一次。

示例

var id_1 = undefined;
useEffect(() => {
    clearTimeout(id_1)
    id_1 = setTimeout(() => {
       success_failure_msg // shoule be test2
    }, 500);
  }, [success_failure_msg]);
  
  success_failure_msg = "test";
  success_failure_msg = "test2"

正确的做法是您提供的第二个。要回答您的问题,您真的必须了解我们为什么要清除超时。

让我们以一个简单的 React 组件为例:

const Comp = () => {
  const [count, setCount] = useState(0);

  useEffect(() => {
    setTimeout(() => {
      setCount(1); // set the count in the timeout
    }, 1000);
  }, [setCount]);

  return (
    <div>count: {count}</div>
  );
}

现在,只要组件被渲染,它就可以工作。但是如果组件在超时解决之前被卸载会发生什么。超时仍然 运行,您将调用 setCount 不再在视图中的组件。

如果您将其更改为您在第一个示例中给出的代码,问题仍然相同:

  useEffect(() => {
    const id_1 = setTimeout(() => {
      clearTimeout(id1); // this does not do anything as the timeout has already run
      setCount(1); // set the count in the timeout
    }, 1000);
  }, [setCount]);

清除超时不会做任何事情,你仍然会有内存泄漏。解决它的唯一方法是 return 来自 useEffect 的函数,当它卸载组件时,该函数将 运行 做出反应。在该函数中,您可以清理代码。

  useEffect(() => {
    const id_1 = setTimeout(() => {
      setCount(1); // set the count in the timeout
    }, 1000);
    
    // React will run this function when it unmounts and so no memory leak
    return () => clearTimeout(id_1)
  }, [setCount]);