怎么在组件卸载时清除定时器

huangapple go评论159阅读模式
英文:

How to clearInterval when component is unmounted

问题

我有下面这段简化的代码。当用户点击“点击我”时,它将启动一个5秒的间隔,然后执行doSomethingImportant()。它工作得很好,除非有人点击另一个组件(工具栏、页脚),将你带到另一个组件。在这种情况下,间隔将一直执行。如何防止这种情况发生?这样在AnswerScreen卸载时,间隔就被清除了?下面的“诀窍”不起作用。

const AnswerScreen = (props) => {

    const [timeout, setTimeout] = useState(false);
    useEffect(() => {        
      return () => { clearInterval(timeout) }
    }, []);
    
    const itemClickHandler = (index, value) => {
      setTimeout(setInterval(() => {
        props.doSomethingImportant();
        return () => { clearInterval(timeout) }
      }, 5000));    
    }

    return (
        <div onClick={() => itemClickHandler(3, 4)}>点击我</div>
    );
}
    
export default connect(null, null)(AnswerScreen);
英文:

I have this simplified code below. When the user clicks on CLICK ME it will start a 5 second interval that after that will doSomethingImportant(). It works well, except on the case someone clicks on another component (Toolbar, footer) that brings you to a different component. In that case, the interval will keep executing all the time. How can I prevent that from happening? So that when AnswerScreen is unmounted, the interval is cleared? The "trick" below doesn't work.

const AnswerScreen = (props) =&gt; {

    const [timeout, setTimeout] = useState(false);
    useEffect(() =&gt; {        
      return () =&gt; { clearInterval(timeout) }
    }, []);
    
    const itemClickHandler = (index, value) =&gt; {
      setTimeout(setInterval(() =&gt; {
        props.doSomethingImportant();
        return () =&gt; { clearInterval(timeout) }
      }, 5000));    
    }

    return (
        &lt;div onClick={() =&gt; itemClickHandler(3, 4)}&gt;CLICK ME&lt;/div&gt;
    );
}
    
export default connect(null, null)(AnswerScreen);

答案1

得分: 1

清除定时器:clearTimeout( id )
===============

&gt; 使用 **`setTimeout`** 时,请使用 `clearTimeout`  

&gt; 使用 **`setInterval`** 时,请使用 `clearInterval`

在路由到另一个组件时清除定时器

useEffect(()=>{
return () => clearTimeout(timeoutRef.current)
},[])

在用户点击按钮2次或更多次时清除上一个定时器 

const AnswerScreen = (props) => {
const timeoutRef = useRef(null);

  const itemClickHandler = (index, value) =&gt; {
      if(timeoutRef.current) clearTimeout(timeoutRef.current)
      timeoutRef.current=setTimeout(setInterval(() =&gt; {
         //做你想做的事情
         props.doSomethingImportant();
      }, 5000));   
}

return (
    &lt;div onClick={() =&gt; itemClickHandler(3, 4)}&gt;点击我&lt;/div&gt;
);

}


<details>
<summary>英文:</summary>

clearTimeout( id )
===============

&gt; With **`setTimeout`** use `clearTimeout`  

&gt; With **`setInterval`** use `clearInterval`

To clear the timeout when routing to another component

useEffect(()=>{
return () => clearTimeout(timeoutRef.current)
},[])

To clear previous timeout when user click the button 2 or more times 

const AnswerScreen = (props) => {
const timeoutRef = useRef(null);

  const itemClickHandler = (index, value) =&gt; {
      if(timeoutRef.current) clearTimeout(timeoutRef.current)
      timeoutRef.current=setTimeout(setInterval(() =&gt; {
         //do what ever you want
         props.doSomethingImportant();
      }, 5000));   
}

return (
    &lt;div onClick={() =&gt; itemClickHandler(3, 4)}&gt;CLICK ME&lt;/div&gt;
);

}


</details>



huangapple
  • 本文由 发表于 2023年3月12日 16:09:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/75711810.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定