我有两个代码,如下所示。
[第一个是显示当前时间的时钟,每秒更新一次。它完美地工作!
第二个是非常相似的代码,但是它没有显示当前时间,而是一个每秒递增的计数器。
这是我们可以看到意外行为的地方,因为在最初的几秒钟之内就可以了,但是从第二个4或5开始(实际上可能是从第一个第二个秒开始发生,但是从第四,第五个第二个可见)。显示所有先前的值(秒)的速度非常快...并且当我们达到约10秒时,甚至看不到这些值。
请注意,如果我放弃了“ setInterval”函数,并且手动增加了单击按钮的值,它将按预期工作(我们在屏幕上只能看到增加的值)。
可能会发生什么?我是新来的反应者,感谢您的帮助;)
代码1:
import React, { useState } from "react";
function App() {
let time = new Date().toLocaleTimeString();
let [now, changeTime] = useState(time);
function getCurrentTime() {
let innerTime = new Date().toLocaleTimeString();
changeTime(innerTime);
}
setInterval(getCurrentTime, 1000);
return (
<div className="container">
<h1>{now}</h1>
<button onClick={getCurrentTime}>Get Time</button>
</div>
);
}
export default App;
代码2:
import React, { useState } from "react";
function App() {
let time = 0;
let [now, changeTime] = useState(0);
function getCurrentTime() {
let innerTime = now;
changeTime(innerTime+1);
}
setInterval(getCurrentTime, 1000);
return (
<div className="container">
<h1>{now}</h1>
<button onClick={getCurrentTime}>Get Time</button>
</div>
);
}
export default App;
index.js如下所示非常简单:
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
const rootElement = document.getElementById("root");
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
rootElement
);
问题:通过无条件设置间隔,将在每个渲染周期实例化该间隔,并且不会清除先前的间隔。
function App() {
let time = 0;
let [now, changeTime] = useState(0);
function getCurrentTime() {
let innerTime = now;
changeTime(innerTime+1);
}
setInterval(getCurrentTime, 1000); // <-- Creates a new interval each render cycle!
return (
<div className="container">
<h1>{now}</h1>
<button onClick={getCurrentTime}>Get Time</button>
</div>
);
}
一个可能的解决方案:如果您只是想要一个自动计数器,那么仅需要状态和设置/清除计时器的效果就可以了:
function Counter() {
const [count, setCount] = useState(0);
useEffect(() => {
// Use functional state update since next state depends on previous
const timerID = setInterval(() => setCount(c => c + 1), 1000);
// return interval cleanup function
return () => clearInterval(timerID);
}, []) // Empty dependency array to invoke effect once when component mounted
return (
<div className="container">
<h1>{count}</h1>
</div>
);
}