为了账号安全,请及时绑定邮箱和手机立即绑定

为什么 clearTimeout 不清除此反应组件中的超时?

为什么 clearTimeout 不清除此反应组件中的超时?

白衣非少年 2021-10-21 14:45:25
我试图在启动新的超时之前清除以前的超时,因为我希望消息显示 4 秒并消失,除非在 4 秒之前弹出新消息。问题:旧超时正在清除当前消息,因此 clearTimeout() 在此组件中不起作用,在这种情况下:  let t; // "t" for "timer"  const [message, updateMessage] = useState('This message is to appear for 4 seconds. Unless a new message replaces it.');  function clearLogger() {    clearTimeout(t);    t = setTimeout(() => {      console.log('wiping message');      updateMessage('');    }, 4000);  }  function initMessage(msg) {    updateMessage(msg);    clearLogger();  }有趣的是,这是有效的:  function clearLogger() {    t = setTimeout(() => {      console.log('wiping message');      updateMessage('');    }, 4000);    clearTimeout(t);  }...但显然违背了目的,因为它会立即消除超时。在实践中,我应该能够每两秒触发一次 initMessage()并且永远不会看到“擦除消息”记录到控制台。
查看完整描述

3 回答

?
POPMUISE

TA贡献1765条经验 获得超5个赞

问题是在每次渲染时, 的值t都会重置为 null。一旦您调用updateMessage,它将触发重新渲染并失去它的价值。功能性反应组件内的任何变量在每次渲染时都会重置(就像在render基于类的组件的功能内一样)。如果要保留引用,则需要保存tusing的值,setState以便可以调用clearInterval.


但是,另一种解决方法是承诺setTimeout. 通过使其成为承诺,您可以消除需求,t因为它在setTimeout完成之前不会解决。完成后,您可以updateMessage('')重置message. 这可以避免您在引用t.


clearLogger = () => {

  return new Promise(resolve => setTimeout(() => updateMessage(''), resolve), 5000));

};


const initMessage = async (msg) => {

  updateMessage(msg);

  await clearLogger();

}


查看完整回答
反对 回复 2021-10-21
?
吃鸡游戏

TA贡献1829条经验 获得超7个赞

我用 useEffect 解决了这个问题。您想清除返回函数中的超时


const [message, updateMessage] = useState(msg);


useEffect(() => {

  const t = setTimeout(() => {

    console.log('wiping message');

    updateMessage('');

  }, 4000);


  return () => {

    clearTimeout(t)

  }

}, [message])




function initMessage(msg) {

  updateMessage(msg);

}


查看完整回答
反对 回复 2021-10-21
?
慕桂英3389331

TA贡献2036条经验 获得超8个赞

在 clearTimeout() 完成后尝试执行 set timeout


clearTimeout(someVariable, function() {    

          t = setTimeout(() => {

      console.log('wiping message');

      updateMessage('');

    }, 4000);


        });


function clearTimeout(param, callback) {

  //`enter code here`do stuff

或者你也可以使用 .then() 。


clearTimeout(param).then(function(){

     t = setTimeout(() => {

          console.log('wiping message');

          updateMessage('');

        }, 4000);

});


查看完整回答
反对 回复 2021-10-21
  • 3 回答
  • 0 关注
  • 642 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信