HooksUtilities & Refs
useFreshRef
Keeps the latest committed value in a stable mutable ref.
About
useFreshRef gives long-lived callbacks access to changing data without reinstalling the resource that owns those callbacks.
Example
import { useEffect, useState } from "react";
import { useFreshRef } from "rooks";
export default function LatestValueTimer() {
const [value, setValue] = useState(0);
const latestValue = useFreshRef(value);
useEffect(() => {
const timer = window.setInterval(() => {
console.log(`Latest value: ${latestValue.current}`);
}, 1_000);
return () => window.clearInterval(timer);
}, [latestValue]);
return (
<button type="button" onClick={() => setValue((current) => current + 1)}>
Value: {value}
</button>
);
}Parameters
value: T— required value copied into the ref after each render.preferLayoutEffect?: boolean— uses an isomorphic layout effect whentrue; otherwise a passive effect. Defaults tofalseand should remain constant across renders.
Return value
Returns a stable MutableRefObject<T>. Its initial .current is the first value.
Behavior and lifecycle
With the default passive effect, .current changes after the commit is painted; immediately before that effect, it can still hold the prior committed value. The layout-effect mode updates before browser paint and falls back to a passive effect on the server. The hook never schedules a render when .current changes.
Compatibility and accessibility
The ref logic is SSR-safe and has no browser dependency. Because ref changes do not render UI, do not use .current alone for user-visible state or accessible status messages.
Related
- useFreshCallback wraps a callback with stable identity and preserves its return value.
- useFreshTick offers a void-callback convenience wrapper.