秒表使用react useState钩子+ setInterval导致额外的间隔启动时恢复



我正在实现一个带有开始和暂停按钮的秒表。开始按钮调用setInterval,暂停按钮调用clearInterval。按开始和暂停按钮按预期工作,但另一个按开始按钮导致两个间隔启动,而代码只创建一个间隔。

import React, {useState} from "react";
function StopWatch() {
const [count, setCount] = useState(0);
const [intervalID, setIntervalID] = useState(undefined);
console.log('Rendering, intervalID =', intervalID);
return (
<div>
<p>Counter: {count}</p>
<button onClick={
() => {
setIntervalID(oldId => {
if (oldId === undefined) {
const newId = setInterval(() => {
setCount(count => count + 1);
}, 1000);
console.log('Started Interval with ID =', newId);
return newId;
} else {
console.log('Skipping, IntervalID =', oldId);
return oldId;
}
});
}
}>Start
</button>
<button onClick={
() => {
setIntervalID(oldId => {
console.log('Stopping IntervalID =', oldId);
clearInterval(oldId);
return undefined;
});
}
}>Pause
</button>
</div>
);
}

这些是按下按钮start, pause, start的控制台日志消息。

Rendering, intervalID = undefined
Started Interval with ID = 10
Rendering, intervalID = 10 
Stopping IntervalID = 10 
Rendering, intervalID = undefined 
Started Interval with ID = 11 
Rendering, intervalID = 11 
Rendering, intervalID = 12

您可以看到,在最后创建了一个ID为12的额外间隔。

问题是由于严格模式。但是我想知道为什么没有关于启动额外间隔的console.log消息。在看了react文档后,我发现了这个。

从React 17开始,React会自动修改控制台方法,如console.log(),使第二次调用时的日志保持沉默生命周期的功能。然而,它可能会导致不希望的行为在某些情况下,可以使用变通方法。

最新更新