composeRefs
Merges several refs into one callback ref, so a part can keep its own ref and still forward the element. Returns React 19 ref cleanups.
Example
Installation
npx shadcn@latest add https://hirael.com/r/compose-refs.jsonUsage
import { composeRefs } from "@/lib/compose-refs"Paths assume the default @/ alias from your components.json.
API
composeRefs()
| Parameter | Type | Default |
|---|---|---|
...refsObject or callback refs to receive the node; `undefined` entries are skipped. | (React.Ref<T> | undefined)[] | none |
Returns
React.RefCallback<T>Source
import type * as React from 'react';
const setRef = <T>(ref: React.Ref<T> | undefined, node: T | null) => {
if (typeof ref === 'function') return ref(node);
if (ref) ref.current = node;
};
/**
* Merges refs, returning React 19 callback-ref cleanups so consumer refs are torn down, not called with null.
* @param refs Object or callback refs to receive the node; `undefined` entries are skipped.
*/
export const composeRefs =
<T>(...refs: (React.Ref<T> | undefined)[]): React.RefCallback<T> =>
(node) => {
const cleanups = refs.map((ref) => setRef(ref, node));
if (!cleanups.some((cleanup) => typeof cleanup === 'function')) return;
return () => {
cleanups.forEach((cleanup, i) => {
if (typeof cleanup === 'function') cleanup();
else setRef(refs[i], null);
});
};
};
Shipped