import { useEffect, useRef } from "react"; /** * Generates a value continuously, animating it. Unlike {@link useGeneratedValue}, this * hook uses a ref to avoid unnecessary re-renders. * * @param getValue A function that returns the value to display. * @param frameMS The duration of a frame. If set to null, the value animates as fast as the browser allows with `requestAnimationFrame`. * @returns */ export const useGeneratedRef = ( getValue: () => string, frameMS: number | null = null ) => { const elementRef = useRef(null); useEffect(() => { let playing = true; let cancelFrame: number | null = null; let cancelTimeout: NodeJS.Timeout | null = null; const doFrame = () => { const amounts = getValue(); if (elementRef.current) { elementRef.current.innerHTML = amounts; } if (playing) { if (frameMS === null) { cancelFrame = requestAnimationFrame(doFrame); } else { cancelTimeout = setTimeout(() => doFrame, frameMS); } } }; doFrame(); return () => { playing = false; if (cancelFrame) { cancelAnimationFrame(cancelFrame); } if (cancelTimeout) { clearTimeout(cancelTimeout); } }; }, [frameMS, getValue]); return { elementRef }; };