Reactの「ref」を渡す魔法:forwardRefで親子を繋ぐ裏ワザを学ぼう!
こんにちは。Reactの世界へようこそ!
コンポーネントを組み合わせて画面を作る楽しさに触れ始めた頃、こんな壁にぶつかったことはありませんか?
「親コンポーネントから、子コンポーネントの中にある『特定のボタン』を直接操作したい……!」
普通、ReactではPropsを使ってデータを渡しますよね。でも、`ref`(DOM要素を直接つまみ上げるための道具)だけは、普通に渡そうとしても「えっ、何のこと?」とReactが困ってしまうんです。
今日は、そんな時に頼りになる「forwardRef」という魔法の杖について、現場の知見を交えて優しく解説しますね。
—
1. なぜ「ref」はそのまま渡せないの?
例え話をしましょう。
あなたは大きな荷物(データ)を、隣の部屋の友人(子コンポーネント)に渡そうとしています。Propsは「手紙」のようなもの。中身は簡単に渡せますよね。
でも、`ref`は「その部屋のドアノブを直接掴んで回す権利」のようなものです。
Reactにおいて、子コンポーネントは「カプセル化」されていて、外から中身を直接覗き込んだり操作したりすることが、基本的には禁止されています。だから、ただ手紙(Props)に「ドアノブ使わせて」と書いても、門前払いされてしまうんです。
そこで登場するのが、`forwardRef`。
これは、「私が責任を持つから、このrefを中まで通してあげて!」と、親から子へ「ドアノブを掴む権利」を転送するための公認ルートなんです。
—
2. forwardRefを使ってみよう!
まずは、シンプルな例を見てみましょう。子コンポーネントの中にある入力フォームに、親からフォーカスを当てる(カーソルを合わせる)という実用的なパターンです。
import React, { forwardRef, useRef } from ‘react’;
// 子コンポーネント:forwardRefで包んで、refを受け取れるようにする
// 第一引数がprops、第二引数がrefという「お約束」があります
const MyInput = forwardRef
return (
{/ 渡ってきたrefを、このinputタグに装着する /}
);
});
// 親コンポーネント
export const Parent = () => {
const inputRef = useRef
const handleClick = () => {
// ボタンを押すと、子コンポーネント内のinputにフォーカスが当たる!
inputRef.current?.focus();
};
return (
);
};
ここがポイント!
- `forwardRef<型A, 型B>`: この書き方がコツです。
- `型A`: `ref`が指す先(今回はHTMLのinput要素なので`HTMLInputElement`)。
- `型B`: `props`の型。
- 「責任のバトンパス」: `forwardRef`を使うことで、`ref`がまるで普通のPropsのように、子の中へスーッと入っていけるようになります。
—
3. 初学者がつまずきやすい「落とし穴」
僕も駆け出しの頃、ここでよく悩みました。「あれ、なんで動かないの?」とならないためのアドバイスを3つ贈ります。
1. `ref`の名前は変えない:
`ref`という名前はReactにとって特別な予約席のようなものです。自分で作ったコンポーネントに`myRef`のように渡しても、自動的には繋がりません。必ず`ref`という名前で渡してくださいね。
2. 型定義で迷ったら:
最初は型定義が難しく感じるはずです。そんな時は、とりあえず `forwardRef
3. 「本当にrefが必要か?」を一度考える:
Reactは「データ(Props)が変化したら画面が変わる」という仕組みが一番綺麗です。`ref`による操作は「最終手段」と考えておくと、コードがぐちゃぐちゃにならず、保守しやすい綺麗な状態を保てますよ。
—
最後に:怖がらないで!
`forwardRef`は、Reactの「カプセル化」という鉄壁の守りを、必要な時だけ特別に解除する「信頼の証」のようなものです。最初は少し複雑に見えるかもしれませんが、これを使えるようになると、ライブラリとの連携や、高度なUI制御がグッと身近になります。
もしコードが動かなくても、それはあなたが成長している証拠です。一つずつエラーメッセージを読んで、少しずつ紐解いていけば、必ず「あ、そういうことか!」と膝を打つ瞬間が訪れますからね。
大丈夫、焦らずいきましょう。応援しています!

コメント