I have 2 question. First, why this code does not work. Second, why this code slow when it comes 2^n -1 for example 1-3-7-15
let time = 0
function App() {
const [mytime, setMytime] = useState(time)
setInterval(() => {
time += 1
setMytime(time)
}, 1000)
return <div> {mytime} </div>
The setInterval gets called each time when mytime changes for rerendering (when you call the setMytime). And the number of setInterval calls grows exponentially. This would lead to a memory leak as well.
You should run it only once. You should use useEffect hook with an empty dependency array.
Try like this.
import { useEffect, useState } from "react";
function App() {
const [mytime, setMytime] = useState(0);
useEffect(() => {
// create a interval and get the id
const myInterval = setInterval(() => {
setMytime((prevTime) => prevTime + 1);
}, 1000);
// clear out the interval using the id when unmounting the component
return () => clearInterval(myInterval);
}, []);
return <div> {mytime} </div>;
}
export default App;
To extend @Amila's answer,
start, stop, reset timer using functions ?useRef(), because useState() will cause render.useState() as it will cause skipping of timer.
useEffect(() => {
return () => clearInterval(currentTimer.current);
}, []);
Use the following code:
const [time, setTime] = useState(0);
const currentTimer = useRef();
useEffect(() => {
return () => clearInterval(currentTimer.current);
}, []);
const startTimer = () => {
currentTimer.current = setInterval(() => {
setTime((prev) => prev + 1);
console.log(time);
}, 1000);
};
const stopTimer = () => {
clearInterval(currentTimer.current);
};
const resetTimer = () => {
clearInterval(currentTimer.current);
setTime(0);
};
return (
<div>
<div>{time}</div>
<button onClick={startTimer}>Start</button>
<button onClick={stopTimer}>Stop</button>
<button onClick={resetTimer}>Reset</button>
</div>
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With