この記事を読む前に、Ref についての記事 を読むことをお勧めします!
ref のフォワーディングとは、親コンポーネントから子コンポーネントに ref を渡すテクニックで、これにより子コンポーネントの DOM 操作などを行うことができます。
それでは、具体的な方法を見ていきましょう!
ref フォワーディング
順を追って ref フォワーディングの実装順について説明します。
- まず、
React.createRef
で Ref オブジェクトを作り、それを子コンポーネントに<Button ref={ref}>
のように ref 属性に指定します。 - 子コンポーネントで
React.forwardRef()
を用いて受け取ります。forwardRef
は引数にprops
、ref
の順で受け取ります。 - 受け取った ref を操作したい DOM ノードの ref 属性に指定します。
この手順を通すと、ref.current
は操作したい子コンポーネントの DOM ノードを指すようになります。
例を以下に示します。
// forwardRefでrefを受け取り、操作したいDOMノードのref属性に指定する
const ForwardingButton = React.forwardRef((props, ref) => (
<button ref={ref}>{props.children}</button>
));
// Refオブジェクトを作り、子コンポーネントのref属性に指定
const ref = React.createRef();
<ForwardingButton ref={ref}>Click me!</ForwardingButton>;
補足
ref フォワーディングを使わずに、つまりReact.forwardRef
を用いない方法で親から子のコンポーネントに ref を渡そうとするとエラーが出ます!
基本的に子コンポーネントの DOM 操作などを行いたい場合は ref フォワーディングを使いましょう。
また、ref のフォワーディング先は DOM ノードだけではなく、クラスコンポーネントのインスタンスに対してもフォワーディングすることができます。
高階コンポーネントでの ref フォワーディング
HOC で forwardRef を使う例を以下に示します。
function logProps(Component) {
class LogProps extends React.Component {
componentDidUpdate(prevProps) {
console.log("old props:", prevProps);
console.log("new props:", this.props);
}
render() {
const { forwardedRef, ...rest } = this.props;
// forwardedRefという名のpropsをrefとして受け取り、コンポーネントに紐づける
return <Component ref={forwardedRef} {...rest} />;
}
}
// forwardRefの第二引数でrefを受け取り、コンポーネントに紐づけている
return React.forwardRef((props, ref) => {
return <LogProps {...props} forwardedRef={ref} />;
});
}