javascript - 为什么 clearTimeout 不清除此 react 组件中的超时?

标签 javascript reactjs settimeout cleartimeout

我试图在启动新超时之前清除以前的超时,因为我希望消息显示 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() 并且永远不会看到“删除消息”记录到控制台。

最佳答案

问题是在每次渲染时,t 的值都被重置为 null。一旦调用 updateMessage,它将触发重新渲染并失去其值(value)。函数式 React 组件中的任何变量都会在每次渲染时重置(就像在基于类的组件的 render 函数中一样)。如果要保留引用,则需要使用 setState 保存 t 的值,以便调用 clearInterval

然而,另一种解决方法是 promise setTimeout。通过 promise ,您无需 t,因为它在 setTimeout 完成之前不会解析。完成后,您可以通过 updateMessage('') 重置 message。这可以避免您在引用 t 时遇到的问题。

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

const initMessage = async (msg) => {
  updateMessage(msg);
  await clearLogger();
}

关于javascript - 为什么 clearTimeout 不清除此 react 组件中的超时?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57995978/

相关文章:

Javascript 定时通知 - setTimeout、setInterval

javascript - 如何将从后端呈现的参数传递给angular2 bootstrap方法

javascript - d3Service/d3-ng2-service TypeScript TS2346 提供的参数与签名不匹配

javascript - <img> src 属性不使用 Jquery 改变

javascript - react 带 : how to make dropDown menu's size fill all of the available space

javascript - 在 IE 中使用 setImmediate() 而不是 setTimeout(func,0)

node.js - 如何在 NodeJS 中创建无限循环

javascript - 第二个 promise 无法正常工作

javascript - console.log 在箭头函数中不起作用

javascript - react JSX : Iterating through a hash and returning JSX elements for each key