こんにちは!Reactの世界へようこそ。
フロントエンドの深淵を覗き込んでいると、必ず一度は「あれ、フォームの値ってどうやって扱うのが正解なんだろう?」と立ち止まる瞬間がありますよね。
今日は、Reactにおけるフォーム管理の二大巨頭、「制御コンポーネント」と「非制御コンポーネント」について、現場の知見を交えながら、肩の力を抜いて紐解いていきましょう。
—
フォームは「お店のレジ」で考えるとわかりやすい
まずは難しい専門用語を置いておいて、身近な「お買い物」で例えてみますね。
1. 制御コンポーネント:すべてを把握する「完璧な店長」
制御コンポーネントは、レジの打ち込み一回ごとに「今、何が売れたか」をすべてノートに記録し、リアルタイムで在庫管理を行う店長のような存在です。
- 特徴: `useState` を使って、入力内容を常にReactの管理下に置きます。
- メリット: 「入力した瞬間にバリデーション(エラーチェック)をする」「入力内容に応じてボタンを無効化する」といった、細やかな演出が得意です。
2. 非制御コンポーネント:必要な時だけ聞く「大らかな店長」
一方の非制御コンポーネントは、普段はレジを放置していて、お客さんが「会計!」と言った瞬間にレジの中身を確認する店長です。
- 特徴: `useRef` を使って、必要なタイミングだけDOMから直接値を取り出します。
- メリット: 頻繁な再レンダリング(画面の描き直し)が起きないので、パフォーマンスに優れています。
—
制御コンポーネントを書いてみよう
まずは、Reactの王道である「制御コンポーネント」から。`onChange` イベントで値をstateに保存する、もっともスタンダードな形です。
import { useState } from ‘react’;
function ControlledForm() {
const [name, setName] = useState(”);
// 入力されるたびにReactのstateが更新されます
const handleChange = (e) => {
setName(e.target.value);
};
const handleSubmit = () => {
alert(`送信内容: ${name}`);
};
return (
現在の入力値: {name}
{/ リアルタイムに反映されます /}
);
}
ここがポイント: `value={name}` と書くことで、Reactが「君の顔色(値)は僕が管理するよ」と宣言しています。これが制御されている状態です。
—
非制御コンポーネントを書いてみよう
次は、DOMから直接値をもぎ取る「非制御コンポーネント」です。ここでは `useRef` という「魔法の杖」を使います。
import { useRef } from ‘react’;
function UncontrolledForm() {
// input要素を指し示す「魔法の杖」を作成
const inputRef = useRef(null);
const handleSubmit = () => {
// 必要な時に、その杖を使って中身を覗き見ます
alert(`送信内容: ${inputRef.current.value}`);
};
return (
);
}
ここがポイント: Reactは入力中に何が起きたか関知しません。「送信!」という合図があった瞬間にだけ、`ref` を通じてDOMという現場に確認しに行きます。
—
で、結局どっちを使えばいいの?
現場でよく聞かれる質問ですが、結論から言うと「基本は制御コンポーネント、重たい時は非制御コンポーネント」という使い分けがベターです。
制御コンポーネントを選ぶべきケース
- 入力内容に応じてリアルタイムにエラーメッセージを出したい。
- 入力内容に合わせて送信ボタンの色や有効・無効を切り替えたい。
- 複数の入力項目が複雑に絡み合うフォームを作っている。
非制御コンポーネントを選ぶべきケース
- とにかく入力項目が膨大で、一文字打つたびに画面全体が再描画されると重い。
- React外のライブラリ(jQueryなど)と共存させる必要がある。
- フォームの送信時以外、入力値に一切興味がない。
—
最後に:つまずいても大丈夫
Reactを始めたばかりの頃は、「どっちが正解なんだろう?」と迷って手が止まってしまうことがよくあります。でも、どちらの手法もReactが公式に認めている立派な道具です。
まずは「制御コンポーネント」でReactのデータフローに慣れてみてください。そして、フォームが重くなったり、もっとシンプルな実装がいいなと思った時に、「そういえば非制御っていう手もあったな」と思い出していただければ大成功です。
コードはあくまで道具です。あなたが作りたいものに合わせて、柔軟に使いこなしてあげてくださいね。応援しています!

コメント