一覧へ

制御されたフォームと制御されていないフォーム — フォーム入力の扱い

React でフォーム入力を扱う際に使用する、制御されたパターンと制御されていないパターンの違い、それぞれの長所と短所、選択基準について説明します。

中級
|
5
|
検証済み (2026-07)
進捗0/55 (0%)

Controlled vs Uncontrolled — フォーム入力の取り扱い

このトピックを終えると

Reactでinputを扱う2つの方法の違いを理解し、状況に応じて適切な方法を選択できるようになります。


HTMLの基本的な動作

HTMLのinputは、自身で値を管理します。

html
<input type="text" />

ユーザーが入力すると、input自体が値を保存します。JavaScriptが関与しなくても動作します。

Reactでは、この値をReactが管理するか、input自身に管理させるかを選択します。


Controlled: Reactが管理

jsx
function SearchBox() {
  const [query, setQuery] = useState("");

  return (
    <input
      value={query}
      onChange={(e) => setQuery(e.target.value)}
    />
  );
}

valueをstateに指定し、onChangeでstateを更新します。ユーザーがタイピングするたびに:

  1. onChangeイベントが発生
  2. setQueryでstateが変更
  3. 再レンダリング
  4. inputに新しい値が反映

Reactがinputの値を制御します。そのため、"Controlled"と呼ばれます。

利点:入力値に対する完全な制御。リアルタイムのバリデーション、入力制限、フォーマットが可能です。

jsx
function PhoneInput() {
  const [phone, setPhone] = useState("");

  const handleChange = (e) => {
    const cleaned = e.target.value.replace(/\D/g, "");
    if (cleaned.length <= 11) {
      setPhone(cleaned);
    }
  };

  return <input value={phone} onChange={handleChange} />;
}

数字のみ入力でき、11文字を超えることはできません。


Uncontrolled: DOMが管理

jsx
function FileUpload() {
  const inputRef = useRef(null);

  const handleSubmit = () => {
    const file = inputRef.current.files[0];
    console.log(file.name);
  };

  return (
    <div>
      <input type="file" ref={inputRef} />
      <button onClick={handleSubmit}>Upload</button>
    </div>
  );
}

refを使ってDOM要素に直接アクセスし、値を読み取ります。React stateを経由しません。input自身が値を管理し、必要に応じて読み取ります。

ファイルinputはセキュリティ上の理由から、valueをプログラムで設定することができないため、uncontrolledでしか使用できません。


選択基準

Controlledを使用する場合:

  • リアルタイムのバリデーション(メールアドレス形式の確認、文字数制限)
  • 入力値に応じて異なるUIを即座に表示する必要がある場合
  • 複数のinputの値を1つのstateで管理する場合
  • フォームを送信する前にデータを加工する必要がある場合

Uncontrolledを使用する場合:

  • ファイルアップロード
  • 値を送信時にのみ読み取る場合
  • 既存のHTMLフォームをReactに移行する場合

ほとんどの場合、Controlledがデフォルトの選択肢です。Reactの公式ドキュメントもControlledを推奨しています。


重要なポイント

Controlledコンポーネントは、React stateがinputの値を管理します。リアルタイムの制御が可能です。 Uncontrolledコンポーネントは、DOMが値を管理し、refを使って必要に応じて読み取ります。 ほとんどのフォームでは、Controlledがデフォルトの選択肢です。

💬 質問・コメント

0件のコメント

ログインせずに投稿できます。ゲスト投稿は投稿者自身で編集・削除できません。

0/2000

読み込み中...