设置超时触发两次

问题描述 投票:0回答:1

这是我为页面准备的 React 代码:

function ExportViewerPage(): JSX.Element {
  const [hasPrinted, setHasPrinted] = useState(false);

  if (!hasPrinted) {
    setHasPrinted(true);
    console.log("Inside if loop, hasPrinted: ", hasPrinted)
    setTimeout(() => {
      console.log("Executing setTimeout: ", hasPrinted)
    });
  }

  return (<div>Page</div>)
}

export default ExportViewerPage;

最终,代码应该执行一次

setTimeout
函数中的代码。然而,它实际上执行了两次,如控制台所示:

Inside if loop, hasPrinted:  false
Executing setTimeout:  false
Executing setTimeout:  false

奇怪的是,在

setTimeout
函数之前的控制台日志只执行一次,所以
setTimeout
没有被调用两次并且
hasPrinted
设置正确。这在 Chrome 和 Firefox 上都发生了。

我确实注意到,如果我在

reactStrictMode
文件中关闭
next.config.js
setTimeout
只会触发一次。但是我仍然对为什么
setTimeout
reactStrictMode
开启时触发两次但它上面的控制台日志只记录一次感到困惑。

javascript reactjs settimeout
1个回答
1
投票

问题是由于严格模式。根据docs,严格模式在开发中调用某些函数两次以帮助识别副作用。

特别之处在于

setTimeout
上方的控制台日志也没有触发两次。这可以通过文档中的这个片段来解释:

注意: 在 React 17 中,React 会自动修改控制台方法,如 console.log() 以在第二次调用生命周期函数时静默日志。但是,在某些可以使用解决方法的情况下,它可能会导致意外行为。

由于我使用的是 React 17,所以控制台日志的第二次调用被 React 静音了,所以这就是我感到困惑的原因。

请注意,在 React 18 中不再是这种情况:

从 React 18 开始,React 不再压制任何日志。但是,如果您安装了 React DevTools,第二次调用的日志将略微变暗。 React DevTools 还提供了一个设置(默认关闭)来完全抑制它们。

© www.soinside.com 2019 - 2024. All rights reserved.