I'm using requestAnimationFrame to update every 1 sec a timer.
const [secondsPassed, setSecondsPassed] = useState(0)
const t0Ref = useRef(Date.now())
const requestRef = useRef()
const targetValueRef = useRef(0)
const updateSecondsPassed = useCallback(() => {
const time = Date.now() - t0Ref.current
const nextValue = time * 0.001
if (nextValue >= sessionTime) {
console.log('Reset to 0')
setSecondsPassed(0)
return
}
const targetValue = targetValueRef.current
if (nextValue >= targetValue) {
console.log(`Update ${targetValue - 1} -> ${nextValue | 0}`)
setSecondsPassed(targetValue)
targetValueRef.current = targetValue + 1
}
requestRef.current = requestAnimationFrame(updateSecondsPassed)
}, [sessionTime])
useEffect(() => {
if (playbackState === 'initial' || playbackState === 'stopped') {
setSecondsPassed(0)
targetValueRef.current = 0
}
if (playbackState === 'playing') {
t0Ref.current = Date.now()
requestRef.current = requestAnimationFrame(updateSecondsPassed)
}
if (playbackState === 'paused') {
console.log(secondsPassed)
}
if (playbackState === 'resumed') {
// Code here...
}
return () => cancelAnimationFrame(requestRef.current)
}, [playbackState])
The problem is I tried everything on the 'resumed' playbackState block and it waits for the number of seconds already passed before starting to count again.
Solved it by resetting the t0Ref to Date.now() minus the already passed seconds in milliseconds:
if (playbackState === 'resumed') {
t0Ref.current = Date.now() - secondsPassed * 1000
requestRef.current = requestAnimationFrame(updateSecondsPassed)
}