【サクッとReact】refをフォワーディングして子コンポーネントのDOM操作を行おう

Posted: September 12, 2020

この記事を読む前に、前回の記事 を読むことをお勧めします!
refのフォワーディングとは、親コンポーネントから子コンポーネントにrefを渡すテクニックで、これにより子コンポーネントのDOM操作などを行うことができます。
それでは、具体的な方法を見ていきましょう!

refフォワーディング

順を追ってrefフォワーディングの実装順について説明します。

  1. まず、React.createRefでRefオブジェクトを作り、それを子コンポーネントに<Button ref={ref}> のようにref属性に指定します。
  2. 子コンポーネントでReact.forwardRef() を用いて受け取ります。forwardRef は引数にpropsrefの順で受け取ります。
  3. 受け取った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} />;
  });
}