Skip to content
usefy

useMergedRefs

Lifecycle & refs

Merge multiple refs into one — the missing piece for forwardRef components

Install

$ npm install @usefy/use-merged-refs

Quick start

useMergedRefs.tsx
import { forwardRef, useRef } from "react";
import { useMergedRefs } from "@usefy/use-merged-refs";

const Input = forwardRef<HTMLInputElement, InputProps>((props, forwardedRef) => {
  // The component needs its own ref (to measure, focus, observe…) *and* must
  // honor the forwarded ref. Merge them into one.
  const localRef = useRef<HTMLInputElement>(null);
  const ref = useMergedRefs(localRef, forwardedRef);

  return <input {...props} ref={ref} />;
});

API reference

useMergedRefs(...refs)

function useMergedRefs<T>(
  ...refs: PossibleRef<T>[]
): (node: T | null) => (() => void) | void;

Merges the given refs into a single, memoized callback ref. Pass any number of callback refs, ref objects, or null / undefined. The returned callback assigns the node to every ref and only changes identity when one of the refs does.

ParamTypeDescription
...refsPossibleRef<T>[]The refs to merge. PossibleRef<T> is Ref<T> | undefined; nullish entries are skipped.

Returns a callback ref. When any provided callback ref returns a React 19 cleanup, the callback returns a cleanup that runs each ref's cleanup (resetting the others to null); otherwise it returns void.

mergeRefs(...refs)

The non-hook core of useMergedRefs — same merging logic, without memoization. Use it when composing refs outside of render (e.g. in a class component or a one-off).

import { mergeRefs } from "@usefy/use-merged-refs";

const ref = mergeRefs(refA, refB);

setRef(ref, value)

Assign a single value to one ref, whatever its form (callback ref → invoked; ref object → .current set; nullish → ignored). Returns the callback ref's cleanup if it returned one.

Go deeper

This page is the quick reference. For every example, prop, and edge case, read the full README — or open Storybook to change props live.

More in lifecycle & refs