我刚开始学习反应,我正在看一个处理状态和挂钩的教程。它只是处理每 1000 毫秒更新一次的时间(我是这么认为的)。
import React from "react";
let count = 0;
function App() {
const now = new Date().toLocaleTimeString();
let [time, setTime] = React.useState(now);
function updateTime(){
const newTime = new Date().toLocaleTimeString();
setTime(newTime);
count++;
console.log(count);
console.log(new Date().getMilliseconds());
}
setInterval(updateTime, 1000);
return (
<div className="container">
<h1>{time}</h1>
<button onClick = {updateTime}>time</button>
</div>
);
}
export default App;
本教程的目的只是一个关于如何更新时间的简单示例,但我注意到它每 1000 毫秒更新多次(突发)。我怀疑每次更改挂钩时都会呈现新组件,但旧组件仍然在那里更新并产生更多组件,导致调用每 1000 毫秒呈指数增长。
我很好奇这里发生了什么?我将如何着手假设有一个每 1000 毫秒更新一次的简单计数器? setTime(count)
显然不起作用
原文由 B.James 发布,翻译遵循 CC BY-SA 4.0 许可协议
问题:在您当前的实现中,
setInterval
将在每次组件呈现时调用(即,也将在设置时间状态后调用)并将 创建一个新的间隔- 这产生了这种“指数增长” “ 如您在控制台中所见。正如评论部分所解释的:
useEffect
在 React 中处理功能组件时,这将是处理这种情况的最佳方式。看看我下面的例子。useEffect
这里只会在初始组件渲染后运行(当组件安装时)。在您的场景中,这是“空数组作为第二个参数”的完美用法,因为您只需要在安装组件时设置间隔并在卸载时清除间隔。看看
useEffect
返回的函数。这是我们的清理功能,将在组件卸载时运行。这将“清理”,或者在这种情况下,清除组件不再使用的时间间隔。我写了一个小应用程序来演示我在这个答案中涵盖的所有内容: https ://codesandbox.io/s/so-react-useeffect-component-clean-up-rgxm0?file=/src/App.js
我合并了一个小的路由功能,以便可以观察到组件的“卸载”。
我的旧答案(不推荐):
每次组件重新渲染时都会创建一个新的间隔,这就是您为时间设置新状态时发生的情况。我要做的是在设置新间隔之前清除之前的间隔(
clearInterval
)https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval