首页 > 解决方案 > 在 React 功能组件中调用了两次 setTimeout 回调?

问题描述

考虑以下代码:

import React from "react";

function App() {
  console.log("render");

  setTimeout(() => {
    console.log("time is up");
  }, 2000);

  return <div>nothing to see here</div>;
}

export default App;

期望以下输出:

render
time is up

但是 Chrome 控制台中的真正输出是:

在此处输入图像描述

注意2之前的time is up,向我们显示time is up被输出了两次。

我不明白为什么时间到了输出两次。谁能解释一下?

标签: javascriptreactjscreate-react-app

解决方案


该组件被渲染两次,因为 CRA 默认设置了 React 的严格模式,其中包括尝试帮助您检测副作用(强调我的):

严格模式不能自动为您检测副作用,但它可以通过使它们更具确定性来帮助您发现它们。 这是通过有意双重调用以下函数来完成的

  • 类组件constructor,rendershouldComponentUpdate方法
  • 类组件静态getDerivedStateFromProps方法
  • 功能组件体
  • 状态更新函数( 的第一个参数setState
  • 传递给useStateuseMemo或的函数useReducer

到目前为止,这已被以下帖子所涵盖:


但是,您可能会期望两者都"render" "time is up"记录两次。没有发生的原因,据我所知还没有在 SO 上介绍,是React 被更新以故意抑制重复的日志:

当我们在 DEV 中以严格模式进行双重渲染时,这会通过在第二次渲染过程中临时修补全局控制台对象来禁用 console.log。

这仅适用于console.logs 直接在上述函数中,它不包括setTimeout回调,因此第二个console.log("render")被吞下但第二个console.log("time is up")不是。


推荐阅读