Skip to content

useComposedRefs

Edit on GitHub
@volvo-cars/react-utils v1.3.0

Merges multiple React refs into a single ref callback. Use it when a component needs to forward a ref to consumers while also keeping its own internal ref.

import { useRef, type Ref } from 'react';
import { useComposedRefs } from '@volvo-cars/react-utils';
type SearchFieldProps = React.ComponentPropsWithoutRef<'input'> & {
ref?: Ref<HTMLInputElement>;
};
function SearchField({ ref: forwardedRef, ...props }: SearchFieldProps) {
const internalRef = useRef<HTMLInputElement | null>(null);
const ref = useComposedRefs(forwardedRef, internalRef);
return (
<div>
<input {...props} ref={ref} type="search" />
<button type="button" onClick={() => internalRef.current?.focus()}>
Focus input
</button>
</div>
);
}

useComposedRefs accepts any number of ref objects, callback refs, null, or undefined values. Each provided ref receives the same node:

import { useRef } from 'react';
import { useComposedRefs } from '@volvo-cars/react-utils';
function Example() {
const inputRef = useRef<HTMLInputElement | null>(null);
const ref = useComposedRefs(inputRef, (node) => {
if (node) {
node.dataset.ready = 'true';
}
});
return <input ref={ref} type="search" />;
}

If you need the low-level utility without a hook, use composeRefs. Prefer useComposedRefs inside React components so the merged ref callback stays stable between renders.

import { useRef } from 'react';
import { composeRefs } from '@volvo-cars/react-utils';
function Example() {
const firstRef = useRef<HTMLInputElement | null>(null);
const secondRef = useRef<HTMLInputElement | null>(null);
return <input ref={composeRefs(firstRef, secondRef)} type="search" />;
}

useComposedRefs<T>(...refs) accepts any number of refs. Each item can be:

  • a callback ref
  • a ref object created with useRef
  • null or undefined

The hook returns a single ref callback to pass to an element.

  • Every provided ref receives the same node when React attaches the element
  • When React clears the ref, object refs are reset and callback refs are called with null