useRaf
Runs the latest callback every animation frame while active.
About
useRaf manages a recurring frame loop using the raf package's requestAnimationFrame polyfill. Use it for visual updates that should align with browser painting.
Examples
import { useState } from "react";
import { useRaf } from "rooks";
export default function FrameClock() {
const [active, setActive] = useState(false);
const [elapsed, setElapsed] = useState(0);
useRaf((frameMs) => setElapsed((value) => value + frameMs), active);
return (
<section>
<p>Elapsed while active: {Math.round(elapsed)}ms</p>
<button type="button" onClick={() => setActive((value) => !value)}>
{active ? "Stop" : "Start"}
</button>
</section>
);
}Parameters
| Argument | Type | Default | Meaning |
|---|---|---|---|
callback | (timeElapsed: number) => void | required | Latest callback, with wall-clock milliseconds since the previous frame. |
isActive | boolean | required | Keeps the frame loop running while true. |
Return value
The hook returns void. Callback return values do not control the loop.
Behavior and lifecycle
When activated, the effect schedules one frame. Each tick schedules the next frame before invoking the callback and uses Date.now() to compute elapsed time. Changing only the callback does not restart the loop. Deactivation or unmount cancels the most recently scheduled frame. Exceptions are not caught; because the next frame is scheduled first, throwing is not a supported way to stop the loop.
Compatibility and accessibility
No frame is scheduled during server rendering. The raf package supplies its environment fallback, but visible animation still belongs on the client. Check reduced-motion preferences and avoid using frame-by-frame state updates for information that could be represented with native CSS or static content.