作者:速度coinmer | 来源:互联网 | 2023-09-25 16:45
考虑以下代码:
import React from "react";
function App() {
console.log("render");
setTimeout(() => {
console.log("time is up");
}, 2000);
return nothing to see here
;
}
export default App;
我期望以下输出:
render
time is up
但是Chrome 控制台中的真实输出是:
注意2
before time is up,向我们显示time is up输出了两次。
我不明白为什么时间到了会输出两次。谁能解释一下?
回答
该组件被渲染两次,因为 CRA默认设置了 React 的严格模式,其中包括试图帮助您检测副作用(强调我的):
严格模式无法自动为您检测副作用,但它可以通过使它们更具确定性来帮助您发现它们。
这是通过有意重复调用以下函数来完成的:
- 类成分
constructor
,render
和shouldComponentUpdate
方法
- 类组件静态
getDerivedStateFromProps
方法
- 函数组件体
- 状态更新器函数(的第一个参数
setState
)
- 函数传递给
useState
,useMemo
或useReducer
到目前为止,这包括以下帖子:
- 为什么我的简单反应组件打印控制台两次?
- 为什么console.log 在react js 中记录两次?
- 为什么 useState 会导致组件在每次更新时渲染两次?
但是,您可能然后期待双方"render"
和 "time is up"
被记录两次。没有发生的原因,据我所知还没有在 SO 上涵盖,是React 已更新以故意抑制重复日志:
当我们在 DEV 中以严格模式进行双重渲染时,这会通过在第二次渲染过程中临时修补全局控制台对象来禁用 console.log。
这仅适用console.log
于上面提到的函数中的 s ,它不包括setTimeout
回调,因此第二个console.log("render")
被吞掉,但第二个console.log("time is up")
没有。