はじめに
こんにちは。アメリカ在住で独学エンジニアを目指している Taira です。
React でフォームを扱うときによく出てくる用語に 制御コンポーネント(Controlled Component) と 非制御コンポーネント(Uncontrolled Component) があります。
「正直、どっちで書いても動くし、意識してない…」という方も多いと思います。
しかし、それぞれにメリット・デメリットがあり、場面によって使い分けることでコードがすっきりします。
この記事では、制御コンポーネントと非制御コンポーネントの違いや使い分けのポイントを解説します。
制御コンポーネント (Controlled Component)
制御コンポーネントは フォーム要素の値を React の state で管理する方法 です。
入力値は常に state
が持ち、onChange
で更新します。
サンプルコード
import { useState } from 'react';
export const ControlledInput = () => {
const [name, setName] = useState('');
return (
<div>
<input
type="text"
value={name} // state が値を制御
onChange={(e) => setName(e.target.value)}
/>
<p>入力した名前: {name}</p>
</div>
);
};
非制御コンポーネント (Uncontrolled Component)
非制御コンポーネントは フォーム要素の値を React ではなく DOM に持たせる方法 です。
値が必要なときだけ ref
を使って取り出します。
サンプルコード
import { useRef } from 'react';
export const UncontrolledInput = () => {
const inputRef = useRef<HTMLInputElement>(null);
const handleClick = () => {
alert(`入力した名前: ${inputRef.current?.value}`);
};
return (
<div>
<input type="text" ref={inputRef} />
<button onClick={handleClick}>名前を表示</button>
</div>
);
};
メリット・デメリット比較
項目 | 制御コンポーネント | 非制御コンポーネント |
---|---|---|
値の管理 | React の state | DOM |
値の取得 | state 経由 |
ref 経由 |
データの一貫性 | 高い(Single Source of Truth) | 低い |
コード量 | やや多い | 少なめ |
バリデーション | 簡単(onChange で可能) | 面倒(ref で値を取る必要あり) |
パフォーマンス | 入力ごとに再レンダリング | レンダリング少なめ |
主な用途 | 複雑なフォーム、バリデーション | 簡単な入力、ファイル入力 |
非制御コンポーネントが役立つケース
「Controlled だけでいいのでは?」と思うかもしれませんが、Uncontrolled が便利な場面もあります。
-
ファイル入力
<input type="file" />
→ ファイルを state に持たせるのは非効率なので
ref
で扱うのが自然。 -
既存ライブラリとの統合
DOM の値を直接操作するライブラリ(古い jQuery プラグインなど)を組み込むときに便利。 -
大量フォームでのパフォーマンス
何百もの入力がある場合、Controlled にすると入力のたびに再レンダリングが発生。
Uncontrolled にすれば DOM が勝手に値を保持してくれるので軽くなることもある。 -
一時的な入力(検索バーなど)
入力値を「送信時にだけ使えればいい」なら Controlled で state を縛る必要はない。
実務での使い分け
-
制御コンポーネントを選ぶ場面
- サインアップフォームやプロフィール編集などの複雑なフォーム
- 入力値に応じてボタンの有効/無効を切り替える
- 入力内容をグローバル state(Zustand, Redux など)に渡す
-
非制御コンポーネントを選ぶ場面
- ファイルアップロードフォーム
- シンプルな検索フォーム
- 既存のライブラリと組み合わせるとき
- パフォーマンスを重視する大量フォーム
まとめ
- 制御コンポーネント → 値を React state で管理。データの一貫性が高く、複雑なフォームに向く。
- 非制御コンポーネント → 値を DOM に持たせる。シンプルな用途や特殊な入力で有効。
実務では 基本は Controlled が推奨。
ただし「ファイル入力」「検索バー」「大量フォーム」など、ケースによっては Uncontrolled を選んだほうがシンプルで効率的 です。
👉 普段 Controlled ばかり使っている方も、場面によって Uncontrolled を取り入れると開発が楽になるかもしれません。