外側から受け取ったrefとは別に、コンポーネント内部で定義したrefも一緒に子コンポーネントに渡したい場合を調べた
調べたところ、カスタムhookで作る必要があった
useMergeRefという名でよくutilとして実装されている模様
実装例:
import { useCallback } from 'react'; function useMergeRef<T>(...refs: Array<React.Ref<T> | undefined>) { return useCallback((node: T | null) => { refs.forEach(ref => { if (!ref) return; if (typeof ref === 'function') { ref(node); // 関数型refの場合、直接呼び出す } else if (ref && 'current' in ref) { (ref as React.MutableRefObject<T | null>).current = node; // オブジェクト型refの場合、currentに設定 } }); }, [refs]); } export default useMergeRef;
使い方
外部refと内部refをマージして渡す
import React, { forwardRef, useRef } from 'react'; import useMergeRef from './useMergeRef'; type Props = { externalRef?: React.Ref<HTMLDivElement>; }; const MyComponent = forwardRef<HTMLDivElement, Props>(({ externalRef }, forwardedRef) => { const internalRef = useRef<HTMLDivElement>(null); const mergedRef = useMergeRef(internalRef, externalRef, forwardedRef); return <div ref={mergedRef}>Hello, World!</div>; }); export default MyComponent;
これで外部refと内部refを簡単に統合して扱えるようになった