FluentUI Compat

Home > @cascadiacollections/fluentui-compat > useMergedRefs

useMergedRefs() function

Hook to merge multiple refs into a single ref callback.

When working with React refs, you often need to handle multiple refs on the same element: - Your own ref for component logic - A forwarded ref from a parent component - Refs from third-party libraries

This hook merges all refs into a single callback ref that updates all of them.

**Features**: - **Flexible input**: Accepts any combination of callback refs, ref objects, and null/undefined - **Type safe**: Full TypeScript support with proper type inference - **Performance optimized**: Memoizes the callback to prevent unnecessary re-renders - **Cleanup safe**: Properly cleans up all refs when the element unmounts - **SSR compatible**: Works correctly with server-side rendering

Signature:

export declare function useMergedRefs<T = any>(...refs: Array<React.Ref<T> | undefined | null>): React.RefCallback<T>;

Parameters

Parameter

Type

Description

refs

Array<React.Ref<T> | undefined | null>

Array of refs to merge (callback refs, ref objects, or null/undefined)

Returns:

React.RefCallback<T>

A single callback ref that updates all provided refs

Example 1

// Forward ref while keeping internal ref
const FancyInput = React.forwardRef<HTMLInputElement, Props>((props, forwardedRef) => {
  const internalRef = useRef<HTMLInputElement>(null);
  const mergedRef = useMergedRefs(internalRef, forwardedRef);

  useEffect(() => {
    // Can use internalRef for component logic
    if (internalRef.current) {
      internalRef.current.focus();
    }
  }, []);

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

Example 2

// Combine multiple refs from different sources
function EditableDiv({
  contentRef,
  containerRef,
  externalRef
}: {
  contentRef?: React.Ref<HTMLDivElement>;
  containerRef?: React.Ref<HTMLDivElement>;
  externalRef?: React.Ref<HTMLDivElement>;
}) {
  const internalRef = useRef<HTMLDivElement>(null);
  const mergedRef = useMergedRefs(
    internalRef,
    contentRef,
    containerRef,
    externalRef
  );

  return <div ref={mergedRef} contentEditable />;
}

Example 3

// With third-party libraries
function ResizablePanel({ onResize }: { onResize: (size: number) => void }) {
  const panelRef = useRef<HTMLDivElement>(null);
  const resizeObserverRef = useRef<ResizeObserver | null>(null);

  // Library might provide a ref
  const [thirdPartyRef, setThirdPartyRef] = useState<HTMLDivElement | null>(null);

  const mergedRef = useMergedRefs(panelRef, setThirdPartyRef);

  useEffect(() => {
    if (panelRef.current) {
      resizeObserverRef.current = new ResizeObserver(entries => {
        onResize(entries[0].contentRect.height);
      });
      resizeObserverRef.current.observe(panelRef.current);
    }

    return () => resizeObserverRef.current?.disconnect();
  }, [onResize]);

  return <div ref={mergedRef}>Resizable content</div>;
}

Example 4

// Conditional refs
function ConditionalRefExample({
  shouldUseExternalRef,
  externalRef
}: {
  shouldUseExternalRef: boolean;
  externalRef?: React.Ref<HTMLDivElement>;
}) {
  const internalRef = useRef<HTMLDivElement>(null);

  // Can pass undefined/null refs - they'll be ignored
  const mergedRef = useMergedRefs(
    internalRef,
    shouldUseExternalRef ? externalRef : null
  );

  return <div ref={mergedRef}>Content</div>;
}
  • Edit this page
In this article
Back to top FluentUI React complimentary components and utilities focused on render performance