I'm currently trying to create a timer with corresponding progress bar. See this Image : (https://i.sstatic.net/WSklt.png)
The logic for my timer works fine:
const [timerIsRunning, setTimerIsRunning] = React.useState(false);
let intervalID: NodeJS.Timeout;
useEffect(() => {
if (timerIsRunning) {
intervalID = setInterval(() => {
setSeconds((seconds) => {
// Return updated time to parent component
if (seconds === 0) {
setTimerIsRunning(false);
return seconds;
} else {
console.log("SET NEW TIME: ");
return seconds - 1;
}
});
}, 1000);
}
// CleanUp
return () => clearInterval(intervalID);
}, [timerIsRunning]);
To calculate a smooth progress I try to make steps in the size of 1. My progress should go from 100 to 0.
For example taking a 10 seconds timer. In each second my progress should go down 10 steps.
For this I calculate the interval time for my progress:
const step = 100 / startTimer;
const intervalTime = 1000 / step;
let interval: NodeJS.Timeout;
useEffect(() => {
if (timerIsRunning) {
interval = setInterval(() => {
setProgress((progress) => {
console.log("SET NEW PROGRESS: ");
return progress - 1;
});
}, intervalTime);
}
// }
return () => clearInterval(interval);
}, [timerIsRunning]);
MY PROBLEM:
The problem im facing now is that my timer and progress is desynced. The progress isnt finished when the timer is. My guess is, that the progress only goes down by 9 steps instead of 10. But I really don't know why.
As u can see in the following logs:
progress 98
TimerButton.tsx:69 progress 97
TimerButton.tsx:69 progress 96
TimerButton.tsx:69 progress 95
TimerButton.tsx:69 progress 94
TimerButton.tsx:69 progress 93
TimerButton.tsx:69 progress 92
TimerButton.tsx:69 progress 91
TimerButton.tsx:72 seconds 9
TimerButton.tsx:69 progress 90
TimerButton.tsx:69 progress 89
TimerButton.tsx:69 progress 88
TimerButton.tsx:69 progress 87
TimerButton.tsx:69 progress 86
TimerButton.tsx:69 progress 85
TimerButton.tsx:69 progress 84
TimerButton.tsx:69 progress 83
TimerButton.tsx:72 seconds 8
TimerButton.tsx:69 progress 82
TimerButton.tsx:69 progress 81
TimerButton.tsx:69 progress 80
TimerButton.tsx:69 progress 79
TimerButton.tsx:69 progress 78
TimerButton.tsx:69 progress 77
TimerButton.tsx:69 progress 76
TimerButton.tsx:69 progress 75
TimerButton.tsx:69 progress 74
TimerButton.tsx:72 seconds 7
TimerButton.tsx:69 progress 73
TimerButton.tsx:69 progress 72
TimerButton.tsx:69 progress 71
TimerButton.tsx:69 progress 70
TimerButton.tsx:69 progress 69
TimerButton.tsx:69 progress 68
TimerButton.tsx:69 progress 67
TimerButton.tsx:69 progress 66
TimerButton.tsx:69 progress 65
TimerButton.tsx:72 seconds 6
TimerButton.tsx:69 progress 64
TimerButton.tsx:69 progress 63
TimerButton.tsx:69 progress 62
TimerButton.tsx:69 progress 61
TimerButton.tsx:69 progress 60
TimerButton.tsx:69 progress 59
TimerButton.tsx:69 progress 58
TimerButton.tsx:69 progress 57
TimerButton.tsx:69 progress 56
TimerButton.tsx:72 seconds 5
TimerButton.tsx:69 progress 55
TimerButton.tsx:69 progress 54
TimerButton.tsx:69 progress 53
TimerButton.tsx:69 progress 52
TimerButton.tsx:69 progress 51
TimerButton.tsx:69 progress 50
TimerButton.tsx:69 progress 49
TimerButton.tsx:69 progress 48
TimerButton.tsx:69 progress 47
TimerButton.tsx:72 seconds 4
TimerButton.tsx:69 progress 46
TimerButton.tsx:69 progress 45
TimerButton.tsx:69 progress 44
TimerButton.tsx:69 progress 43
TimerButton.tsx:69 progress 42
TimerButton.tsx:69 progress 41
TimerButton.tsx:69 progress 40
TimerButton.tsx:69 progress 39
TimerButton.tsx:69 progress 38
TimerButton.tsx:72 seconds 3
TimerButton.tsx:69 progress 37
TimerButton.tsx:69 progress 36
TimerButton.tsx:69 progress 35
TimerButton.tsx:69 progress 34
TimerButton.tsx:69 progress 33
TimerButton.tsx:69 progress 32
TimerButton.tsx:69 progress 31
TimerButton.tsx:69 progress 30
TimerButton.tsx:69 progress 29
TimerButton.tsx:72 seconds 2
TimerButton.tsx:69 progress 28
TimerButton.tsx:69 progress 27
TimerButton.tsx:69 progress 26
TimerButton.tsx:69 progress 25
TimerButton.tsx:69 progress 24
TimerButton.tsx:69 progress 23
TimerButton.tsx:69 progress 22
TimerButton.tsx:69 progress 21
TimerButton.tsx:69 progress 20
TimerButton.tsx:72 seconds 1
TimerButton.tsx:69 progress 19
TimerButton.tsx:69 progress 18
TimerButton.tsx:69 progress 17
TimerButton.tsx:69 progress 16
TimerButton.tsx:69 progress 15
TimerButton.tsx:69 progress 14
TimerButton.tsx:69 progress 13
TimerButton.tsx:69 progress 12
TimerButton.tsx:69 progress 11
TimerButton.tsx:72 seconds 0
TimerButton.tsx:69 progress 10
TimerButton.tsx:69 progress 9
TimerButton.tsx:69 progress 8
TimerButton.tsx:69 progress 7
TimerButton.tsx:69 progress 6
TimerButton.tsx:69 progress 5
TimerButton.tsx:69 progress 4
TimerButton.tsx:69 progress 3
TimerButton.tsx:69 progress 2
I am not sure you need 2 timers. If your progress depends on a timer where you set seconds you can use useMemo
hook to calculate your progress. Something like:
const [seconds, setSeconds] = useState(0)
const progress = useMemo(() => {
// Place your logic of progress calculation and return new progress value
return newProgressValue
}, [seconds])
useEffect(() => {
setInterval(() => {
// do you logic and set seconds
setSeconds(newValue)
}, 1000)
}, [])