LoginSignup
0
0

[React]フォームとStateの連動(+プルダウンと一覧の連動)

Last updated at Posted at 2023-11-03

はじめに

  • Reactで入力フォームを作る際、入力値をStateに設定するが、入力フォームが増えるとその分Stateを用意するのは面倒
  • Stateの更新時にでプロパティ変数([プロパティ変数名]:値)を使うことで、ひとつのStateで管理できるようになる。

手順解説

1.Stateの定義

  • オブジェクトにして、各プロパティをフォーム要素にする
  const [form, setForm] = useState({
    feedId: data[0].id,
    note: '',
  });

2.フォームの定義

  • value属性にStateのプロパティ値を設定する
  • name属性をStateのプロパティ名と一致させる
  • onChangeイベントに渡す関数は同じものにする
    <select name="feedId" id="feedId" onChange={handleForm}>
      {data.map((v) => (
        <option key={v.id} value={v.id}>
          {v.name}
        </option>
      ))}
    </select>
    ...  
   <input
      type="text"
      name="note"
      value={form.note}
      onChange={handleForm}
    />

3.Stateの設定(onChangeイベントの処理)

  • Stateのプロパティ名と値が、フォームのnameとvalueに一致するため、プロパティ変数で汎用的に設定ができる。
  const handleForm = (e) => {
    setForm({
      ...form, // スプレッド構文でコピー
      [e.target.name]: e.target.value, // 差分を設定する際、プロパティ変数を使用する。
    });
  };

実装例

プルダウンを変更すると一覧が切り替わるコンポーネントを作成する。(テキストボックスとプルダウンのフォーム値をStateと連動)

  • サンプルデータ
list-data.json
[
  {
    "id": 1,
    "name": "プルダウン1",
    "list": [
      {
        "name": "リスト1-1",
        "memo": "めも1-1"
      },
      {
        "name": "リスト1-2",
        "memo": "めも1-2"
      }
    ]
  },
  {
    "id": 2,
    "name": "プルダウン2",
    "list": [
      {
        "name": "リスト2-1",
        "memo": "めも2-1"
      },
      {
        "name": "リスト2-2",
        "memo": "めも2-2"
      }
    ]
  }
]
コンポーネント
import { useState } from 'react';
import listData from '../../data/list-data.json';

export const PullDownAndList = () => {
  const data = listData;

  const [form, setForm] = useState({
    feedId: data[0].id,
    note: '',
  });

  const handleForm = (e) => {
    setForm({
      ...form,
      [e.target.name]: e.target.value,
    });
  };
  // プルダウンの値(form.feedId)に応じた一覧でフィルタする
  const fillerList = () => data.filter((d) => d.id === +form.feedId)[0].list;

  return (
    <div>
      <select name="feedId" id="feedId" onChange={handleForm}>
        {data.map((v) => (
          <option key={v.id} value={v.id}>
            {v.name}
          </option>
        ))}
      </select>
      <div>
        一括メモ:
        <input
          type="text"
          name="note"
          value={form.note}
          onChange={handleForm}
        />
      </div>

      {fillerList().map((l) => (
        <li key={l.name}>
          {l.name} : {l.memo} : {form.note}
        </li>
      ))}
    </div>
  );
};

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0