React フォームの基本

ReactBeginner
オンラインで実践に進む

はじめに

Web 開発において、フォームはユーザーからの入力を収集するために不可欠です。React では、フォームデータの扱いは従来の HTML とは少し異なります。推奨されるアプローチは、「制御されたコンポーネント(controlled components)」と呼ばれるテクニックを使用することです。

制御されたコンポーネントでは、フォームのデータは React コンポーネントの状態(state)によって管理されます。これにより、React の状態が「唯一の真実の情報源(single source of truth)」となり、ユーザーの入力を予測可能な方法で管理、検証、応答することができます。

この実験(lab)では、単一のテキスト入力フィールドと送信ボタンを持つシンプルなフォームを構築します。以下の方法を学びます。

  • JSX でフォーム要素を作成する方法。
  • useStateフックを使用して入力値(value)を管理する方法。
  • onChangeイベントでユーザーの入力を処理する方法。
  • onSubmitイベントでフォームの送信を処理する方法。

この実験(lab)の終わりには、React フォームの基本についてしっかりと理解できるようになります。

onChange 属性を持つ入力要素を作成する

このステップでは、フォームの基本的な構造を作成することから始めます。これには、form 要素とテキスト入力フィールドの追加が含まれます。また、入力値の変更を追跡するために不可欠なonChange属性も追加します。

まず、開発環境を準備しましょう。プロジェクトの依存関係をインストールし、開発サーバーを起動する必要があります。

WebIDE でターミナルを開き、以下のコマンドを一つずつ実行してください。~/project/my-app ディレクトリにいることを確認してください。

cd my-app
npm install

このコマンドは、package.json で定義されている必要なすべてのパッケージをインストールします。

次に、開発サーバーを起動します。

npm run dev -- --host 0.0.0.0 --port 8080

次に、左側のファイルエクスプローラーで my-app/src ディレクトリに移動し、App.jsx ファイルを開きます。このファイルを変更してフォームを追加します。

App.jsx の内容を以下のコードに置き換えてください。<form> タグと、その中に <input> 要素を追加しています。入力要素には onChange 属性が追加されており、これは後で値の変更を処理するために使用されます。

import "./App.css";

function App() {
  return (
    <form>
      <h1>React Form</h1>
      <label>
        Enter your name:
        <input type="text" onChange={() => {}} />
      </label>
    </form>
  );
}

export default App;

ファイルを保存した後、LabEx インターフェースの Web 8080 タブに切り替えてください。テキスト入力フィールドを持つシンプルなフォームが表示されるはずです。変更が表示されない場合は、タブを更新してみてください。現時点では、入力フィールドに文字を入力しても何も起こりませんが、基本的な構造は整っています。

Simple form with text input and label

state を更新する関数で変更を処理する

このステップでは、入力フィールドをインタラクティブにします。これを行うために、コンポーネントの state にその値を格納する必要があります。useStateフックを使用して state 変数とそれを更新する関数を作成します。

まず、'react'ライブラリからuseStateフックをインポートする必要があります。次に、入力の値を持つnameという state 変数を宣言します。

次に、handleChangeという関数を作成します。この関数は、ユーザーが入力フィールドに入力するたびにトリガーされます。この関数内で、useStateによって提供されるsetName関数を使用して、event.target.valueからアクセスできる入力の現在の値でnamestate を更新します。

App.jsxファイルを以下のコードで更新してください。

import { useState } from "react";
import "./App.css";

function App() {
  // Create a state variable 'name' and a function 'setName' to update it
  const [name, setName] = useState("");

  // Define the event handler function
  const handleChange = (event) => {
    setName(event.target.value);
  };

  return (
    <form>
      <h1>React Form</h1>
      <label>
        Enter your name:
        {/* Connect the handler to the onChange event */}
        <input type="text" onChange={handleChange} />
      </label>
    </form>
  );
}

export default App;

これで、入力フィールドに文字を入力すると、handleChange関数が呼び出され、キーストロークごとにnamestate が更新されます。まだ画面上で変更を確認することはできませんが、コンポーネントの state は入力値を追跡するようになりました。これは、制御されたコンポーネントを作成するための前半部分です。

state の値に input の value 属性を設定する

このステップでは、「制御されたコンポーネント」(controlled component)パターンを完成させます。制御されたコンポーネントとは、入力の値を React の state によって駆動するもので、state が「唯一の真実の情報源」(single source of truth)となります。

これを実現するために、<input>要素のvalue属性を直接namestate 変数にバインドする必要があります。これにより、双方向データバインディングが作成されます。

  1. ユーザーが入力するとonChangeがトリガーされ、state が更新されます。
  2. state の更新により再レンダリングが発生し、入力のvalueが新しい state の値に設定されます。

これにより、UI は常にコンポーネントの state と同期していることが保証されます。

App.jsxファイル内の<input>要素を修正し、value属性を追加してください。

import { useState } from "react";
import "./App.css";

function App() {
  const [name, setName] = useState("");

  const handleChange = (event) => {
    setName(event.target.value);
  };

  return (
    <form>
      <h1>React Form</h1>
      <label>
        Enter your name:
        {/* Bind the input's value to the state */}
        <input type="text" value={name} onChange={handleChange} />
      </label>
    </form>
  );
}

export default App;

ファイルを保存した後、Web 8080タブに戻ってください。フォームは同じように見えますが、これで完全に制御されたコンポーネントになりました。入力フィールドの表示は、React コンポーネント内のnamestate 変数によって直接制御されるようになりました。

onClick ハンドラーを持つ submit ボタンを追加する

フォームは、送信方法なしでは完了しません。このステップでは、送信ボタンとフォーム送信を処理するためのイベントハンドラを追加します。

React でフォーム送信を処理する標準的で最もアクセスしやすい方法は、<form>要素自体のonSubmitイベントを使用することです。これにより、ボタンをクリックするか、入力フィールドで「Enter」キーを押すことでフォームを送信できるようになります。

まず、フォーム内にtype="submit"を持つ<button>を追加しましょう。次に、新しいハンドラ関数handleSubmitを作成し、それを<form>要素のonSubmit属性にアタッチします。

App.jsxファイルを以下のコードで更新してください。

import { useState } from "react";
import "./App.css";

function App() {
  const [name, setName] = useState("");

  const handleChange = (event) => {
    setName(event.target.value);
  };

  // Create the submit handler function
  const handleSubmit = (event) => {
    // We will add more logic here in the next step
    console.log("Form was submitted");
  };

  return (
    // Attach the handler to the form's onSubmit event
    <form onSubmit={handleSubmit}>
      <h1>React Form</h1>
      <label>
        Enter your name:
        <input type="text" value={name} onChange={handleChange} />
      </label>
      {/* Add a submit button */}
      <button type="submit">Submit</button>
    </form>
  );
}

export default App;

これで、Web 8080タブに移動すると、「Submit」ボタンが表示されます。それをクリックすると、ページがすぐにリロードされることに気づくかもしれません。これはフォーム送信のデフォルトのブラウザの動作であり、最終ステップで対処します。

submit のデフォルト動作を防ぎ、フォームデータをログに出力する

最終ステップでは、フォームの機能を完成させます。気づいたかもしれませんが、送信ボタンをクリックするとページ全体がリロードされます。React で構築されたようなシングルページアプリケーション(SPA)では、ページをリロードせずに JavaScript を使用してフォーム送信を処理したいと考えます。

これを行うには、handleSubmit関数内でevent.preventDefault()を呼び出す必要があります。eventオブジェクトはイベントハンドラに自動的に渡され、このメソッドはブラウザのデフォルトの動作を停止します。

デフォルトの動作を防止したら、state から送信されたデータにアクセスし、ユーザーにアラートを表示するなど、それを使って何かを行うことができます。

このロジックを実装するために、App.jsxhandleSubmit関数を更新しましょう。

import { useState } from "react";
import "./App.css";

function App() {
  const [name, setName] = useState("");

  const handleChange = (event) => {
    setName(event.target.value);
  };

  const handleSubmit = (event) => {
    // Prevent the default form submission behavior
    event.preventDefault();
    // Show an alert with the submitted name
    alert(`A name was submitted: ${name}`);
  };

  return (
    <form onSubmit={handleSubmit}>
      <h1>React Form</h1>
      <label>
        Enter your name:
        <input type="text" value={name} onChange={handleChange} />
      </label>
      <button type="submit">Submit</button>
    </form>
  );
}

export default App;

ファイルを保存してください。次に、Web 8080タブに移動し、入力フィールドに名前を入力して「Submit」ボタンをクリックします。入力した名前とともにアラートが表示され、ページはリロードされないはずです。

おめでとうございます!React で基本的な制御されたフォームを正常に構築しました。

まとめ

この実験では、「制御コンポーネント」(controlled components)パターンを使用して React でフォームを処理する基本的な原則を学びました。

以下のことを成功させました:

  • JSX を使用して、入力フィールドと送信ボタンを持つフォームを作成しました。
  • useStateフックを使用して、コンポーネントの state 内でフォームのデータを管理しました。
  • onChangeイベントハンドラを実装して、ユーザーが入力するにつれて state を更新し、UI と state を同期させました。
  • onSubmitイベントハンドラでフォーム送信を処理し、event.preventDefault()を使用してブラウザのデフォルトのページリロードを防ぎました。
  • 送信時に state からフォームデータにアクセスしました。

これらの概念は、React アプリケーションでより複雑でインタラクティブなフォームを作成するためのビルディングブロックです。この知識を応用して、複数の入力、異なる入力タイプ、検証ロジックを持つフォームを作成できるようになります。