ReactのforwardRef徹底解説!【初心者向け】

こんにちは! 今回は、Reactでよく使われるforwardRefという機能について、わかりやすく解説していきます。この機能を使うと、コンポーネント間でのデータのやりとりがもっと柔軟になります。

はじめに

Reactでは、通常、親コンポーネントから子コンポーネントにデータを渡すという形でデータフローが行われます。たとえば、以下のコードを見てください。

function ChildComponent({ message }) {
    return <p>{message}</p>;
}

function ParentComponent() {
    return <ChildComponent message="Hello from Parent!" />;
}

このコードでは、ParentComponentからChildComponentに対して、messageというプロパティ(props)が渡されています。Reactの基本的な流れとして、データは親から子へと流れます。

しかし、DOM操作やカスタムロジックが必要な場合には、子コンポーネントが親コンポーネントからrefを受け取り、親が子のDOM要素を直接操作するような仕組みが必要になることがあります。これを可能にするのがforwardRefです。

forwardRefとは?

forwardRefは、親コンポーネントから渡されたrefを子コンポーネント内で受け取り、そのままDOM要素や別の子コンポーネントに渡すためのReactの関数です。

これを使うことで、親コンポーネントが子コンポーネント内部のDOM要素に直接アクセスできるようになります。

たとえば、次のように使います。

import React, { forwardRef } from 'react';

const InputComponent = forwardRef((props, ref) => {
    return <input ref={ref} {...props} />;
});

function ParentComponent() {
    const inputRef = React.createRef();

    const focusInput = () => {
        inputRef.current.focus();
    };

    return (
        <div>
            <InputComponent ref={inputRef} placeholder="Type something..." />
            <button onClick={focusInput}>Focus Input</button>
        </div>
    );
}

コードのポイント

  1. InputComponentは、forwardRefを使って作られています。これにより、親コンポーネントから渡されたrefを受け取り、それを<input>タグのrefに渡しています。
  2. 親コンポーネントの中でReact.createRef()を使い、refを作成しています。
  3. focusInputメソッドでref.current.focus()を呼び出すことで、親コンポーネントから子の<input>にフォーカスを当てることができます。

このように、forwardRefを使うことで、親コンポーネントが直接子のDOM要素を操作できるようになります

通常のrefと何が違うの?

通常、Reactでrefを使う場合、親が直接DOM要素にrefを渡すことができます。しかし、以下のようなケースではforwardRefが必要になります。

例: 通常のrefでは対応できない場合

function InputComponent(props) {
    return <input {...props} />;
}

function ParentComponent() {
    const inputRef = React.createRef();

    return (
        <div>
            <InputComponent ref={inputRef} placeholder="Cannot use ref here!" />
        </div>
    );
}

このコードを実行するとエラーになります。なぜなら、InputComponentは通常の関数コンポーネントであり、refをそのままDOM要素に渡す機能がないからです。

解決策: forwardRefを使う

const InputComponent = React.forwardRef((props, ref) => {
    return <input ref={ref} {...props} />;
});

function ParentComponent() {
    const inputRef = React.createRef();

    const focusInput = () => {
        inputRef.current.focus();
    };

    return (
        <div>
            <InputComponent ref={inputRef} placeholder="Now it works!" />
            <button onClick={focusInput}>Focus Input</button>
        </div>
    );
}

このように、forwardRefを使うことで、親から子へrefを渡すことが可能になります。

応用: コンポーネントとDOMの橋渡し

forwardRefは単にDOM要素にアクセスするだけでなく、コンポーネント間のロジックを柔軟にするためにも使えます。たとえば、次のようにカスタムフックや複雑な構造を持つコンポーネントと組み合わせることができます。

応用例: 高度なコンポーネント

const FancyInput = forwardRef((props, ref) => {
    return (
        <div style={{ border: '1px solid black', padding: '10px' }}>
            <input ref={ref} {...props} />
        </div>
    );
});

function App() {
    const inputRef = React.createRef();

    const focusInput = () => {
        inputRef.current.focus();
    };

    return (
        <div>
            <h1>Fancy Input Example</h1>
            <FancyInput ref={inputRef} placeholder="Click the button to focus" />
            <button onClick={focusInput}>Focus Fancy Input</button>
        </div>
    );
}

この例では、FancyInputが内部に<input>を持ちながら、そのrefを親から操作可能にしています。これにより、見た目や構造が複雑なコンポーネントでも、簡単に親コンポーネントから操作できます。

公式ドキュメント

React公式ドキュメントでは、forwardRefの詳細な仕様について解説されています。ぜひ参考にしてください!

React.forwardRef – React Docs

まとめ

forwardRefを使うと、ReactアプリケーションでのDOM操作やコンポーネント間の連携がとても柔軟になります。

  • 通常のデータフローではできない子コンポーネントのDOM要素へのアクセスが可能。
  • 複雑な構造やカスタムロジックを持つコンポーネントでも、親から簡単に制御可能。

これを機に、ぜひforwardRefを使ったコンポーネント設計に挑戦してみてください!

関連する記事はこちら↓↓

タイトルとURLをコピーしました