useStableForkRef

Merges multiple refs into a single, referentially stable callback ref.

Like useForkRef, but the returned callback keeps a stable reference identity across renders. Under React 19 this stops the ref from being detached and re-attached on every render, avoiding the "Maximum update depth exceeded" loop that can occur when one of the merged refs updates state and another is unstable.

Because the identity is stable, the refs are read when the element attaches or detaches and are not re-distributed when an input ref's identity changes mid-mount. Use useForkRef when you need that — for example, composing a child element's ref that can be swapped.

Import#

import { useStableForkRef } from '@volue/wave-react';

Example#

A component that measures its own element while forwarding the ref. The inline ref callback is a new function every render, but useStableForkRef keeps the merged ref stable — so React attaches it once instead of re-running setWidth on every commit, which with useForkRef could spiral into a "Maximum update depth exceeded" loop.

const Measured = React.forwardRef((props, forwardedRef) => {
const [width, setWidth] = React.useState(0);
const ref = useStableForkRef(forwardedRef, node => {
if (node) {
setWidth(node.getBoundingClientRect().width);
}
});
return (
<div ref={ref} {...props}>
{`Width: ${Math.round(width)}px`}
</div>
);
});

API Reference#

Arguments#

Prop
Type
Default
...refs
(Ref<T> | undefined | null)[]

Returns#

(instance: T | null) => void — A referentially stable callback ref that forwards the instance to all provided refs.