React 速習チュートリアル

React フォーム

HTML と同様に、React でもフォーム(Forms)を使用してユーザーが Web ページとインタラクションを行えるようにします。

1. React へのフォームの追加

React でフォームを追加する方法は、他のエレメントを追加する場合と同じです。

1.1 実装例

ユーザーが名前を入力できるシンプルなフォームを作成します。

function MyForm() {
  return (
    <form>
      <label>名前を入力してください:
        <input type="text" />
      </label>
    </form>
  )
}

createRoot(document.getElementById('root')).render(
  <MyForm />
);

この状態では通常の HTML フォームとして動作し、送信(Submit)するとページがリフレッシュされます。しかし、React 開発においては、通常このような挙動は望ましくありません。

私たちはこのデフォルトの挙動を回避し、React にフォームを制御させたいと考えます。

2. HTML フォーム vs. React フォーム

React では、<input><textarea><select> といったフォーム要素は、従来の HTML とは少し異なる仕組みで動作します。

  • 標準的な HTML: フォーム要素はユーザーの入力に基づいて自身のバリュー(Value)を保持します。例えば、<input type="text"> フィールドは HTML DOM 内で自身の値を追跡します。
  • React: フォーム要素のバリューはコンポーネントの state プロパティに保持され、setState() 関数(または useState の更新関数)を介してのみ更新されます。

言い換えれば、React はコンポーネントの ステート(State) を通じてフォームデータを管理する方法を提供しており、これは 「制御コンポーネント(Controlled Components)」 と呼ばれています。

3. 制御コンポーネント

制御コンポーネントでは、フォームデータが React コンポーネントによって処理されます。インプット要素の値は React のステートによって駆動され、その値への変更はステートを更新するイベントハンドラーを通じて管理されます。

コンポーネントによってデータが処理される際、すべてのデータはコンポーネントのステートに保存されます。useState フックを使用して各入力値を追跡し、アプリケーション全体における「信頼できる唯一の情報源(Single source of truth)」を提供できます。

3.1 useState フックによる管理例

import { useState } from 'react';
import { createRoot } from 'react-dom/client';

function MyForm() {
  // ステート変数の宣言
  const [name, setName] = useState("");

  // 変更イベントを処理する関数
  function handleChange(e) {
    setName(e.target.value);
  }

  return (
    <form>
      <label>名前を入力してください:
        <input
          type="text" 
          value={name} // ステートを値にバインド
          onChange={handleChange} // 変更時にステートを更新
        />
      </label>
      <p>現在の入力内容: {name}</p>
    </form>
  )
}

createRoot(document.getElementById('root')).render(
  <MyForm />
);

3.2 コードの解説

  1. useState フックをインポート: import { useState } from 'react';
  2. ステート変数の宣言: 入力値を保持する変数 name と、それを更新する関数 setName を用意します。 const [name, setName] = useState("");
  3. イベントハンドラーの作成: 入力イベントを受け取り、ステートを更新する関数を定義します。 function handleChange(e) { setName(e.target.value); }
  4. 属性の設定: インプットフィールドの value にステート変数を、onChange 属性に変更イベントハンドラーを設定します。
  5. リアルタイム表示: 値が更新されていることを示すために、現在の値を画面に表示します。

4. 初期値の設定

インプットフィールドに初期値を設定するには、useState の初期引数に値を渡します。

4.1 実装例

名前に初期値として "John" を設定する場合:

function MyForm() {
  // 初期値を "John" に設定
  const [name, setName] = useState("John");

  // ...残りのコード
}