UNPKG

1.36 kBJavaScriptView Raw
1import { useRef } from 'react';
2import useMounted from './useMounted';
3import useStableMemo from './useStableMemo';
4import useWillUnmount from './useWillUnmount';
5
6/**
7 * Returns a controller object for requesting and cancelling an animation freame that is properly cleaned up
8 * once the component unmounts. New requests cancel and replace existing ones.
9 *
10 * ```ts
11 * const [style, setStyle] = useState({});
12 * const animationFrame = useAnimationFrame();
13 *
14 * const handleMouseMove = (e) => {
15 * animationFrame.request(() => {
16 * setStyle({ top: e.clientY, left: e.clientY })
17 * })
18 * }
19 *
20 * const handleMouseUp = () => {
21 * animationFrame.cancel()
22 * }
23 *
24 * return (
25 * <div onMouseUp={handleMouseUp} onMouseMove={handleMouseMove}>
26 * <Ball style={style} />
27 * </div>
28 * )
29 * ```
30 */
31export default function useAnimationFrame() {
32 var isMounted = useMounted();
33 var handle = useRef();
34
35 var cancel = function cancel() {
36 if (handle.current != null) {
37 cancelAnimationFrame(handle.current);
38 }
39 };
40
41 useWillUnmount(cancel);
42 return useStableMemo(function () {
43 return {
44 request: function request(cancelPrevious, fn) {
45 if (!isMounted()) return;
46 if (cancelPrevious) cancel();
47 handle.current = requestAnimationFrame(fn || cancelPrevious);
48 },
49 cancel: cancel
50 };
51 }, []);
52}
\No newline at end of file