React Native - requestAnimationFrame 暂停和恢复

React Native - requestAnimationFrame pause and resume

我正在使用 requestAnimationFrame 每 1 秒更新一次计时器。

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])

问题是我在 'resumed' playbackState 块上尝试了所有方法,它会等待已经过去的秒数,然后再开始重新计数。

感谢阅读!

通过将 t0Ref 重置为 Date.now() 减去已经过去的秒数(以毫秒为单位)解决了这个问题:

   if (playbackState === 'resumed') {
      t0Ref.current = Date.now() - secondsPassed * 1000
      requestRef.current = requestAnimationFrame(updateSecondsPassed)
   }