In the following React Component below, I am trying to add increment count by each second passed so it looks like a stopwatch, but the count is shown as 2, then blinks to 3, and back to 2. Does anyone know how to deal with this bug, and get the count to show up as intended?
import React, { useEffect, useState } from "react";
const IntervalHook = () => {
const [count, setCount] = useState(0);
const tick = () => {
setCount(count + 1);
};
useEffect(() => {
const interval = setInterval(tick, 1000);
return () => {
clearInterval(interval);
};
}, [ count ]);
return <h1> {count} </h1>;
};
export default IntervalHook;
if you want to change some state based on its previous value, use a function:setCount(count => count + 1);
and your useEffect
becomes independant of [ count ]
. Like
useEffect(() => {
const tick = () => {
setCount(count => count + 1);
};
const interval = setInterval(tick, 1000);
return () => {
clearInterval(interval);
};
}, [setCount]);
or you get rid of tick()
and write.
useEffect(() => {
const interval = setInterval(setCount, 1000, count => count + 1);
return () => {
clearInterval(interval);
};
}, [setCount]);
But imo it's cleaner to use a reducer:
const [count, increment] = useReducer(count => count + 1, 0);
useEffect(() => {
const interval = setInterval(increment, 1000);
return () => {
clearInterval(interval);
};
}, [increment]);