Usage
import { useMergeRefs } from "@servicetitan/anvil2";
import { useRef, forwardRef } from "react";
const CustomInput = forwardRef((props, forwardedRef) => {
const internalRef = useRef(null);
const mergedRef = useMergeRefs([internalRef, forwardedRef]);
const focusInput = () => {
internalRef.current?.focus();
};
return <input ref={mergedRef} {...props} />;
});
Parameters
| Parameter | Type | Description |
|---|
refs | Array<Ref<T> | undefined> | Array of React refs to merge |
Return Value
Returns a callback ref that handles all provided refs, or null if all refs are null/undefined.
Features
- Handles both function refs and object refs
- Optimized with
useMemo for performance
- Compatible with floating-ui patterns
Examples
Forwarding Refs with Internal Usage
const FocusableButton = forwardRef((props, forwardedRef) => {
const buttonRef = useRef(null);
const mergedRef = useMergeRefs([buttonRef, forwardedRef]);
useEffect(() => {
// Can use buttonRef internally
if (props.autoFocus) {
buttonRef.current?.focus();
}
}, [props.autoFocus]);
// Parent can also access via forwardedRef
return <button ref={mergedRef} {...props} />;
});
// Usage
const parentRef = useRef(null);
<FocusableButton ref={parentRef} autoFocus />;
Multiple Internal Refs
function ComplexComponent() {
const measureRef = useRef(null);
const animationRef = useRef(null);
const scrollRef = useRef(null);
const mergedRef = useMergeRefs([measureRef, animationRef, scrollRef]);
return <div ref={mergedRef}>Content</div>;
}
Conditional Refs
function ConditionalRefComponent({ shouldMeasure }) {
const measureRef = useRef(null);
const baseRef = useRef(null);
// Only include measureRef when needed
const mergedRef = useMergeRefs([
baseRef,
shouldMeasure ? measureRef : undefined,
]);
return <div ref={mergedRef}>Content</div>;
}
This hook is similar to the useMergeRefs hook from floating-ui and follows the same patterns.Last modified on January 23, 2026