アルアカ - Arcadia Academia

Arcadia Academiaは「エンジニアリングを楽しむ」を合言葉に日本のデジタル競争力を高めることをミッションとするテックコミュニティです。

Reactで動的フォームを実装する方法

Featured image of the post

Reactでフォームを実装する際に、ユーザーが入力項目を追加したり削除したりできる動的フォームを作成することは、特にアンケートや申請フォーム、タスク管理などのアプリケーションで役立ちます。この記事では、Reactを使って動的フォームを実装する方法を詳しく説明し、簡単なコード例も紹介します。

[目次を開く]

1. 動的フォームの仕組み

通常、フォームは固定された数の入力フィールド(テキスト、セレクトボックス、チェックボックスなど)で構成されますが、動的フォームではこれらのフィールドを追加・削除して、柔軟に構成することが可能です。動的フォームの典型的なユースケースは、以下のようなシナリオです。

  • ユーザーが任意の数のタスクや項目を追加できるリスト
  • アンケートで「次の質問を追加」のように、ユーザーが質問を追加可能
  • 複数の入力行(氏名、年齢、住所など)を自由に増やすフォーム

動的フォームをReactで実装する場合、フォームの入力状態(state)を管理し、リスト構造やオブジェクトで各フィールドのデータを効率よく扱うのがポイントです。

2. 動的フォームの基本的な実装手順

ここでは、タスク追加用のシンプルな動的フォームを例にとり、Reactでの実装手順を見ていきましょう。

必要な技術要素

  • React Hooks: useStateで状態管理を行います。
  • フィールドを追加する際の状態変更。
  • リストのマッピングとフォームのレンダリング。

サンプルコード

以下のコードは、動的なタスクリストフォームを作成する例です。

import React, { useState } from "react";

const DynamicForm = () => {
  // フォームの各入力フィールドを配列で管理
  const [tasks, setTasks] = useState([{ name: "" }]);

  // 新しいタスク入力フィールドを追加する関数
  const addTask = () => {
    setTasks([...tasks, { name: "" }]);
  };

  // 指定したタスクフィールドを削除する関数
  const removeTask = (index) => {
    const updatedTasks = tasks.filter((_, i) => i !== index);
    setTasks(updatedTasks);
  };

  // フィールドの値を更新する関数
  const handleInputChange = (index, event) => {
    const updatedTasks = tasks.map((task, i) =>
      i === index ? { ...task, name: event.target.value } : task
    );
    setTasks(updatedTasks);
  };

  // フォームの送信時の処理
  const handleSubmit = (event) => {
    event.preventDefault();
    console.log("Submitted tasks:", tasks);
  };

  return (
    <form onSubmit={handleSubmit}>
      {tasks.map((task, index) => (
        <div key={index}>
          <input
            type="text"
            placeholder={`Task ${index + 1}`}
            value={task.name}
            onChange={(event) => handleInputChange(index, event)}
          />
          <button type="button" onClick={() => removeTask(index)}>
            削除
          </button>
        </div>
      ))}
      <button type="button" onClick={addTask}>
        タスクを追加
      </button>
      <button type="submit">送信</button>
    </form>
  );
};

export default DynamicForm;

コードの解説

  1. 状態の初期化

    useStatetasksという配列を管理しています。各タスクはオブジェクトとして格納され、ここではシンプルにnameフィールドだけを持っています。

  2. タスクの追加

    addTask関数で、既存のtasks配列をスプレッド演算子で展開し、新しい空のタスクオブジェクトを追加します。setTasksで更新して再レンダリングします。

  3. タスクの削除

    removeTask関数では、指定されたインデックス以外の要素をfilterで抽出してtasksを更新します。

  4. 入力値の変更

    handleInputChange関数は、mapで配列内のオブジェクトを更新し、特定のインデックスのオブジェクトのnameフィールドだけを変更しています。

  5. フォーム送信

    handleSubmit関数で、フォームが送信されると現在のtasks配列がコンソールに出力されます。APIへの送信や、Reduxなどのグローバル状態に保存するなどの実装もここで行えます。

3. バリデーションとエラーハンドリング

動的フォームには、各フィールドの値をチェックするバリデーション機能が必要な場合があります。以下のような方法で実装が可能です。

const handleSubmit = (event) => {
  event.preventDefault();
  // バリデーション: 空欄のタスクがないかチェック
  const hasEmptyField = tasks.some((task) => task.name.trim() === "");
  if (hasEmptyField) {
    alert("すべてのタスクに名前を入力してください。");
    return;
  }
  console.log("Submitted tasks:", tasks);
};

handleSubmit関数内で、someメソッドを使ってタスク名が空白のフィールドがないかをチェックし、エラー時にはアラートを表示します。

4. 応用: 入力フィールドの種類を動的に変える

さらに応用として、各フィールドの種類を変えたい場合には、以下のようにタスクオブジェクトにタイプを持たせ、タイプごとに異なる入力をレンダリングすることが可能です。

{tasks.map((task, index) => (
  <div key={index}>
    {task.type === "text" ? (
      <input
        type="text"
        placeholder={`Task ${index + 1}`}
        value={task.name}
        onChange={(event) => handleInputChange(index, event)}
      />
    ) : (
      <input
        type="number"
        placeholder={`Number ${index + 1}`}
        value={task.name}
        onChange={(event) => handleInputChange(index, event)}
      />
    )}
    <button type="button" onClick={() => removeTask(index)}>
      削除
    </button>
  </div>
))}

task.typeを条件分岐させ、typetextの場合はテキスト入力、それ以外の場合は数値入力フィールドを表示します。

まとめ

Reactを使った動的フォームの実装方法を紹介しました。ユーザーが自由にフィールドを増減できるフォームは、利便性が高く、インタラクティブなWebアプリケーションで役立ちます。ReactのuseStatemapfilterなどを組み合わせることで、簡単に動的フォームが構築可能です。ぜひ、実際のプロジェクトに取り入れてみてください。

フロントエンド開発を学びたいですか?

React・Next.jsなど、モダンなフロントエンド開発をサポートします。

  • Reactの基礎から実践まで学びたい
  • Next.jsでアプリを作りたい
  • TypeScriptを使いこなしたい
まずは30分の無料相談

相談は完全無料・オンラインで気軽に

あなたを爆速で成長させるメンタリングプログラムはこちら

メンタープログラムバナー

React・フロントエンドを本格的に学ぶなら

テックアカデミー
無料相談はこちら