setTimeout 回调在 React 功能组件中调用了两次?
setTimeout callback called twice in React functional component?
考虑以下代码:
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控制台的输出是:
注意 time is up 之前的 2
,向我们显示 time is up 输出了两次。
不明白为什么时间到了输出了两次。谁能解释一下?
React.StrictMode 是一项旨在缓解开发人员发现与 React Lifecycle
相关的问题的功能
只有当您 运行 处于开发模式并使用额外规则(例如渲染组件)多次渲染时才会发生。
我认为文档很好地解释了这一点。 StrictMode: React
可以理解,人们第一次注意到它会很烦人!
我认为这里的问题是您没有将 setTimeout 放在 useEffect 中。这意味着当应用程序重新呈现时,另一个超时将开始并导致您发现的问题。尝试这样的事情。
import React, {useEffect} from "react";
function App() {
console.log("render");
useEffect(() => {
const timer = setTimeout(() => {
console.log('time is up');
}, 2000);
return () => {
clearTimeout(timer);
}
}, []);
return <div>nothing to see here</div>;
}
export default App;
组件渲染了两次,因为 CRA 默认设置了 React 的 strict mode,其中包括试图帮助您检测副作用(强调我的):
Strict mode can’t automatically detect side effects for you, but it
can help you spot them by making them a little more deterministic.
This is done by intentionally double-invoking the following functions:
- 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
到目前为止,这已包含在以下帖子中:
但是,您可能希望 "render"
和 "time is up"
都被记录两次。没有发生的原因,据我所知,在 SO 上尚未涵盖,是 React was updated 故意抑制重复日志:
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
s,不包括 setTimeout
回调,因此第二个 console.log("render")
被吞没,但第二个 console.log("time is up")
不是。
考虑以下代码:
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控制台的输出是:
注意 time is up 之前的 2
,向我们显示 time is up 输出了两次。
不明白为什么时间到了输出了两次。谁能解释一下?
React.StrictMode 是一项旨在缓解开发人员发现与 React Lifecycle
相关的问题的功能只有当您 运行 处于开发模式并使用额外规则(例如渲染组件)多次渲染时才会发生。
我认为文档很好地解释了这一点。 StrictMode: React
可以理解,人们第一次注意到它会很烦人!
我认为这里的问题是您没有将 setTimeout 放在 useEffect 中。这意味着当应用程序重新呈现时,另一个超时将开始并导致您发现的问题。尝试这样的事情。
import React, {useEffect} from "react";
function App() {
console.log("render");
useEffect(() => {
const timer = setTimeout(() => {
console.log('time is up');
}, 2000);
return () => {
clearTimeout(timer);
}
}, []);
return <div>nothing to see here</div>;
}
export default App;
组件渲染了两次,因为 CRA 默认设置了 React 的 strict mode,其中包括试图帮助您检测副作用(强调我的):
Strict mode can’t automatically detect side effects for you, but it can help you spot them by making them a little more deterministic. This is done by intentionally double-invoking the following functions:
- Class component
constructor
,render
, andshouldComponentUpdate
methods- Class component static
getDerivedStateFromProps
method- Function component bodies
- State updater functions (the first argument to
setState
)- Functions passed to
useState
,useMemo
, oruseReducer
到目前为止,这已包含在以下帖子中:
但是,您可能希望 "render"
和 "time is up"
都被记录两次。没有发生的原因,据我所知,在 SO 上尚未涵盖,是 React was updated 故意抑制重复日志:
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
s,不包括 setTimeout
回调,因此第二个 console.log("render")
被吞没,但第二个 console.log("time is up")
不是。