第10回:フォーム入力を同期する!Controlled Components(制御コンポーネント)の仕組み

lang

前回:条件分岐で表示を切り替える「条件付きレンダリング」の極意では、状況に応じてUIを出し分けるテクニックを学びました。

今回は、Webアプリの要である「入力フォーム」を攻略します。 Reactには 「制御コンポーネント(Controlled Components)」 という独特の考え方があります。これを知ると、入力されたデータをReactが完全に支配し、リアルタイムでバリデーション(入力チェック)をかけたり、送信データを加工したりすることが自由自在になります。


1. 「制御コンポーネント」って何?

普通のHTMLのフォームは、入力された文字を「ブラウザ自身」が記憶しています。しかし、Reactではそのやり方はおすすめしません。

  • HTML標準: ブラウザが勝手に文字を覚えている。
  • React流: すべての文字を「State(状態)」に持たせ、Reactが管理する。

入力欄の値をReactのStateと「同期」させることで、プログラム側から「今、何が入力されているか」を常に把握できるようにします。これが「制御(コントロール)されている」状態です。


2. フォームを支配する「3つのステップ」

第2回の環境構築第6回のuseStateで学んだ知識を組み合わせて、以下の手順で実装します。

  1. Stateを用意する: 入力値を保存する場所を作る。
  2. valueに紐付ける: inputタグの値をStateに固定する。
  3. onChangeで更新する: キーを叩くたびにStateを書き換える。

3. 【実践】リアルタイム入力フォーム

ユーザーが名前を入力すると、その場で文字数をカウントし、空欄のときは送信ボタンを押せないようにする「賢いフォーム」を作ってみましょう。 第2回の環境で作成した App.jsx を書き換えてください。

App.jsx(最小構成版)

JavaScript

import React, { useState } from 'react';

export default function App() {
  // 1. 入力値を管理するState(初期値は空文字)
  const [name, setName] = useState("");

  // 送信時の処理
  const handleSubmit = (e) => {
    e.preventDefault(); // JavaScriptのポイント:ページのリロードを防ぐ
    alert(`送信されました: ${name}`);
  };

  return (
    <div style={{ textAlign: 'center', marginTop: '50px' }}>
      <h1>お名前入力フォーム</h1>

      <form onSubmit={handleSubmit}>
        {/* 2. valueをStateに固定し、3. onChangeで同期する */}
        <input 
          type="text"
          value={name}
          onChange={(e) => setName(e.target.value)}
          placeholder="名前を入力..."
        />
        
        {/* [第9回]の知識:条件付きでボタンを無効化(disabled) */}
        <button type="submit" disabled={name.length === 0}>
          送信する
        </button>
      </form>

      {/* リアルタイムに文字数を表示 */}
      <p>現在の文字数: {name.length} 文字</p>
      
      {name.length > 10 && (
        <p style={{ color: 'red' }}>※10文字以内で入力してください</p>
      )}
    </div>
  );
}

CodeSandboxで制御コンポーネントを体験する


4. コードの解説(JavaScript & React)

JavaScriptのポイント

  • e.preventDefault(): HTMLの form は送信ボタンを押すとページをリロードしようとします。React(SPA)ではリロードさせたくないため、この命令でブラウザの標準動作をキャンセルします。
  • string.length: 文字列の長さを取得するJavaScriptの基本プロパティです。これを使ってバリデーションを行います。

Reactのポイント

  • value={name}: これがあるおかげで、もしプログラム側から setName("") を実行すれば、入力欄の中身もパッと空になります。
  • データの流れ: 「入力 → onChange発動 → State更新 → 再描画 → inputのvalueが変わる」というサイクルが爆速で回っています。

5. 2026年の学び:なぜ「制御」する必要があるのか?

2026年現在、AIによるフォーム補完や、複雑な多ステップの入力画面が増えています。 制御コンポーネントにしておけば、**「入力された瞬間、別の部品(グラフやプレビュー画面など)を同時に更新する」**といった高度な動きが非常に簡単に実装できるようになります。

「データは常にStateにある」という安心感が、React開発の最大のメリットです。


今回のまとめ

  1. 制御コンポーネント は、ReactのStateとフォーム値を同期させること。
  2. valueonChange をセットで使うのが鉄則。
  3. e.preventDefault() で、余計なページリロードを防ぐ。
  4. Stateで管理しているからこそ、入力チェック(バリデーション) が簡単になる。

次回予告:ついに登場!副作用の番人

これまでは「ユーザーが何かをした」あとの動きを扱ってきました。 次は、「画面が表示された瞬間」や「データが書き換わったあと」など、特定のタイミングで自動的に処理を実行する方法を学びます。API通信には欠かせない知識です。

次回、「第11回:useEffect入門:API連携やタイマー処理など『副次作用』を操る方法」。 React学習の最大の山場であり、最も面白い「ライフサイクル」の世界へ。お楽しみに!


本日の宿題: サンプルコードの input の下に、新しく「メールアドレス用」のStateと input を追加してみてください。2つの入力欄を同時に管理することはできますか?

コメント

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