MrB*_*r77 6 javascript reactjs react-hooks
我在函数中使用“setTimout()”,但没有在“useEffect()”中调用该函数,我是否还需要找到清除超时的方法?
const RandomComponent = () =>{
const [clicked, setClicked] = useState(false);
const aFunction = () => {
setTimeout(()=>{
setClicked(true);
},1000);
}
return (
<div>
<button onClick={aFunction}>Click me!</button>
</div>
)
}
Run Code Online (Sandbox Code Playgroud)
像上面的代码,在这种情况下我需要清除超时吗?谢谢
*更新的问题:
const RandomComponent = () =>{
const [clicked, setClicked] = useState(false);
const aFunction = (evt) => {
return setTimeout(()=>{
setClicked(true);
},30000);
}
useEffect(()=>{
return ()=>{
// how to clear setTimeout in 'aFunction' when I unmount this component?
}
});
return (
<div>
<button onClick={aFunction}>Click me!</button>
</div>
)
}
Run Code Online (Sandbox Code Playgroud)
如果您希望计时器在尚未触发的情况下不触发,则只需清除超时即可。如果它已经被触发,或者您不关心它将来是否触发,则不需要取消它。
由于您在单击按钮时启动计时器,因此如果计时器回调在运行时使用状态信息(问题中的回调没有),它关闭的状态信息可能是过时的,但它可以获得新鲜的状态信息如果需要,可以通过 setter 函数。但是,如果计时器可能在组件卸载后触发,那么使用这样的 setter 会导致有关更新已卸载组件上的状态的错误。很难为您提供一个通用的解决方案,因为通用的解决方案通常不如特定于您在计时器回调中执行的操作的解决方案。
在您提出的评论中:
如果到了时候我需要在卸载组件时清理/清除函数中的 setTimeout,我该怎么做?因为如果我在 useEffect 中调用 setTimeout,我可以将 setTimeout 放入变量中,并将clearTimeout(theSetTimoutVariable) 放入 useEffect 中的返回函数内,但是如何在将由带有事件参数的 onClick 按钮调用的函数中执行此操作?
事实是我不知道“正确”的 React 方法来做到这一点,但我想知道。
我知道一种方法,即使用useEffect空依赖项数组和非状态实例数据,如下所示:
// A utility function that cancels a timer callback if necessary and
// returns a 0 you can assign to the timer handler variable
function cancelTimer(handle) {
if (handle) {
clearTimer(handle);
}
return 0;
}
const Example = () => {
// Non-state instance data
const {current: instance} = useRef({});
// Cleanup on dismount
useEffect(() => {
// Mounting
// ...
return () => {
// Dismounting
// If we have an outstanding timer, cancel it
instance.timer = cancelTimer(instance.timer);
};
}, []); // <=== Empty array means the callback is only called on mount,
// and the one it returns is only called on dismount
const onButtonClick = () => {
instance.timer = cancelTimer(instance.timer);
instance.timer setTimeout(() => {
// ...
}, 1000);
};
return (/*...*/);
};
Run Code Online (Sandbox Code Playgroud)