Skip to content

Instantly share code, notes, and snippets.

@yannamsellem
Created June 22, 2021 13:26
Show Gist options
  • Select an option

  • Save yannamsellem/32d6022757df6cc3bbce9f6d50855b3a to your computer and use it in GitHub Desktop.

Select an option

Save yannamsellem/32d6022757df6cc3bbce9f6d50855b3a to your computer and use it in GitHub Desktop.
Handle requestAnimationFrame with react hook
import { useCallback, useEffect, useRef, useState } from 'react'
/** @param {() => unknown} callback */
export default function useAnimationFrame(callback, initial = false) {
const handlerRef = useRef(callback)
const [started, setStarted] = useState(initial)
useEffect(() => {
handlerRef.current = callback
}, [callback])
useEffect(() => {
let handle = null
let timer = null
const loop = () => {
if (!started) return
// eslint-disable-next-line no-unused-expressions
handlerRef.current?.()
timer = setTimeout(() => {
handle = requestAnimationFrame(() => loop())
}, 40)
}
handle = requestAnimationFrame(() => loop())
return () => {
cancelAnimationFrame(handle)
clearTimeout(timer)
if (started) setStarted(false)
}
}, [started])
const dispose = useCallback(() => setStarted(false), [])
const resume = useCallback(() => setStarted(true), [])
return { dispose, resume }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment