useMergedRefs
useMergedRefs 是一个合并多个 ref 到单个 ref 的 hook。当你需要在单个 dom 节点上使用多个 ref 时,请使用此 hook。
useMergedRefs 接受任意数量的 ref(回调 ref、RefObject 或 undefined),返回一个将 DOM 节点转发给所有 ref 的单一回调 ref。这消除了在同一元素上手动同步多个 ref 的需要。返回的 ref 是稳定的,统一处理 ref 对象和回调 ref。
使用场景
- 将来自
React.forwardRef的转发 ref 与另一个 hook(例如useHover、useFocus)使用的内部 ref 合并 - 在同一 DOM 元素上附加多个独立行为(测量、交叉观察、拖拽处理)
- 构建复合组件或组件库,库和使用者都需要 ref 访问
注意事项
- 处理所有 ref 类型:无缝支持
RefObject、回调 ref 和undefined值。 - SSR 安全:返回的回调 ref 不会自行访问任何浏览器 API。
- 参见
useHover和其他接受 ref 的元素 hook,可以通过useMergedRefs合并。
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 ? '已悬停!' : isFocused ? '已聚焦!' : '悬停或聚焦我'} </button> <p>按 'F' 键聚焦按钮</p> </div> ); }; render(<Demo/>)
Result
API
useMergedRef
Returns
(node: T | null) => void: 合并多个 ref 的函数
Arguments
| 参数名 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| refs | - | PossibleRef<T>[] | - |
PossibleRef
export type PossibleRef<T> = Ref<T> | undefined;