setTimeout回调在React功能组件中被调用过两次? [英] setTimeout callback called twice in React functional component?

查看:87
本文介绍了setTimeout回调在React功能组件中被调用过两次?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下代码:

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控制台中的真实输出是:

But the real output in the Chrome console is:

请注意时间到了之前的 2 ,向我们显示了时间到了了两次.

Note the 2 before time is up, showing us that time is up was output twice.

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

I don't understand why time is up is output twice. Can anyone explain this?

推荐答案

由于CRA设置了React的严格模式可以帮助您检测到副作用(强调我的意思)

The component is rendered twice because CRA sets React's strict mode by default, which among other things tries to help you detect side effects (emphasis mine):

严格模式无法自动为您检测副作用,但是可以使它们更具确定性,从而帮助您发现它们.这是通过有意重复调用以下功能来完成的:

  • 类组件 constructor render shouldComponentUpdate 方法
  • 类组件静态 getDerivedStateFromProps 方法
  • 功能组件主体
  • 状态更新程序功能( setState 的第一个参数)
  • 传递给 useState useMemo useReducer
  • 的函数
  • Class component constructor, render, and shouldComponentUpdate methods
  • Class component static getDerivedStateFromProps method
  • Function component bodies
  • State updater functions (the first argument to setState)
  • Functions passed to useState, useMemo, or useReducer

到目前为止,这已涵盖在以下帖子中:

So far, this is covered by posts like:

但是,您可能随后希望两次记录渲染" 时间已到" .据我所知,尚未发生的未发生的原因是

However, you might then expect both "render" and "time is up" to be logged twice. The reason that doesn't happen, which as far as I can find hasn't been covered yet on SO, is that React was updated to deliberately suppress the duplicate logs:

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

This disables console.log by temporarily patching the global console object during the second render pass when we double render in strict mode in DEV.

这仅直接适用于上述功能中的 console.log ,其中不包含 setTimeout 回调,因此第二个 console.log("render")被吞下,但第二个 console.log(时间到了")没有被吞下.

This applies only to console.logs directly in the functions mentioned above, which doesn't include setTimeout callbacks, so the second console.log("render") is swallowed but the second console.log("time is up") is not.

这篇关于setTimeout回调在React功能组件中被调用过两次?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆