useMergedRefs
useMergedRefs is a hook that merges multiple refs into a single ref. Use this hook when you need to use more than one ref on a single dom node.
useMergedRefs accepts any number of refs (callback refs, RefObjects, or undefined) and returns a single callback ref that forwards the DOM node to all of them. This eliminates the need to manually synchronize multiple refs on the same element. The returned ref is stable and handles both ref objects and callback refs uniformly.
When to Use
- Combining a forwarded ref from
React.forwardRefwith an internal ref used by another hook (e.g.,useHover,useFocus) - Attaching multiple independent behaviors (measurement, intersection observation, drag handling) to the same DOM element
- Building compound components or component libraries where both the library and the consumer need ref access
Notes
- Handles all ref types: Works with
RefObject, callback refs, andundefinedvalues seamlessly. - SSR-safe: The returned callback ref does not access any browser APIs on its own.
- See also
useHoverand other element hooks that accept refs, which can be combined viauseMergedRefs.
Usage
Live Editor
function Demo() { const hoverRef = useRef(null); const buttonRef = useRef<HTMLButtonElement>(null); const isHovered = useHover(hoverRef); const [isFocused, toggleFocus] = useToggle(false); const mergedRef = useMergedRefs(hoverRef, buttonRef); useEffect(() => { const handleKeyPress = (event) => { if (event.key === 'f' || event.key === 'F') { buttonRef.current?.focus(); } }; window.addEventListener('keypress', handleKeyPress); return () => { window.removeEventListener('keypress', handleKeyPress); }; }, []); const handleFocus = () => toggleFocus(true); const handleBlur = () => toggleFocus(false); return ( <div> <button ref={mergedRef} onFocus={handleFocus} onBlur={handleBlur} style={{ padding: '10px 20px', backgroundColor: isHovered ? 'lightblue' : isFocused ? 'lightyellow' : 'white', border: '1px solid black', cursor: 'pointer', outline: isFocused ? '2px solid blue' : 'none', }} > {isHovered ? 'Hovered!' : isFocused ? 'Focused!' : 'Hover or Focus me'} </button> <p>Press 'F' key to focus the button</p> </div> ); }; render(<Demo/>);
Result
API
useMergedRef
Returns
(node: T | null) => void: A function that merges multiple refs
Arguments
| Argument | Description | Type | DefaultValue |
|---|---|---|---|
| refs | - | PossibleRef<T>[] | - |
PossibleRef
export type PossibleRef<T> = Ref<T> | undefined;