I am trying to use the useEffect hook as a way to create an async timer in react. The logic is inside of timeFunc(), and the useEffect is working such that it calls the function every 1000ms. The weird part is, for some reason when timeFunc() gets called (every one sec) it's only accesses the old variable values, (specifically "paused"). For example, if the interval starts with a value of "paused" being false, even if I change 'paused' to be true (paused is a state variable passed in by the parent component), timeFunc() will still think paused is false. Can't figure it out. Any help appreciated!
Code:
//TIMER MANAGER
let timeFunc = () => {
if(paused == false){
let delta = Math.trunc((new Date() - resumedTime)/1000);
setProgress(delta);
console.log('test + ' + paused);
} else {
clearInterval(interval);
}
}
useEffect(() => {
let interval = null;
interval = setInterval(() => {
timeFunc();
}, 1000);
return () => clearInterval(interval);
}, [initialized]);
The timeFunc
depends on having an up-to-date value of paused
, but it doesn't exist in the useEffect
's dependency array.
Either add it to the dependency array and also store the time until the next interval in state, or use a ref for paused
instead (with a stable reference) (or in addition to state), eg:
const pausedRef = useRef(false);
// ...
const timeFunc = () => {
if (!pausedRef.current) {
// ...
// to change it:
pausedRef.current = !pausedRef.current;
Also note that
let interval = null;
interval = setInterval(() => {
timeFunc();
}, 1000);
simplifies to
const interval = setInterval(timeFunc, 1000);