1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

あなたのReactフォーム、まだsetStateを分けてるの?一括管理の最適解はこれ!

Last updated at Posted at 2025-05-22

はじめに

Reactでフォームを作成する際、複数のinput要素の値を効率的に状態管理するには、handleChange関数をうまく設計することが重要です。本記事では、handleChange関数を使ってformDataの状態を一元的に更新する方法を紹介します。

よくある課題:inputごとに個別のsetState?

フォームに複数の入力欄があると、以下のようにsetState関数をinputごとに分けて書いてしまいがちです。

const [formData, setFormData] = useState({ name: '', email: '' });

const handleNameChange = (e) => setFormData({ ...formData, name: e.target.value });
const handleEmailChange = (e) => setFormData({ ...formData, email: e.target.value });

このようなコードは冗長になりがちで、input項目が増えるたびに関数を追加する必要があります。

解決策:スプレッド文+動的key更新

以下のように、inputタグに設定されたname属性を活用することで、すべてのinput要素に対する状態更新を1つの関数にまとめることができます。

const handleChange = (e) => {
  setFormData({ 
    ...formData, 
    [e.target.name]: e.target.value 
  });
};
  • e.target.name でどのフィールドかを特定
  • e.target.value をそのフィールドの新しい値としてセット
  • オブジェクトスプレッド構文 (...formData) によって、既存の値は保持され、該当のキーだけが更新されます

使用例:複数のinputに対応

MultiStepForm.jsx
import { useState } from 'react';

const initialFormData = {
  name: '',
  email: '',
  password: '',
};

export default function MultiStepForm() {
  const [step, setStep] = useState(1);
  const [formData, setFormData] = useState(initialFormData);

  const handleChange = (e) => {
    setFormData({
      ...formData,
      [e.target.name]: e.target.value,
    });
  };

  const nextStep = () => setStep((prev) => prev + 1);
  const prevStep = () => setStep((prev) => prev - 1);

  return (
    <div>
      {step === 1 && (
        <div>
          <h2>Step 1: 名前</h2>
          <input
            type="text"
            name="name"
            value={formData.name}
            onChange={handleChange}
            placeholder="Your Name"
          />
          <button onClick={nextStep}>次へ</button>
        </div>
      )}
      {step === 2 && (
        <div>
          <h2>Step 2: メールアドレス</h2>
          <input
            type="email"
            name="email"
            value={formData.email}
            onChange={handleChange}
            placeholder="Your Email"
          />
          <button onClick={prevStep}>戻る</button>
          <button onClick={nextStep}>次へ</button>
        </div>
      )}
      {step === 3 && (
        <div>
          <h2>Step 3: パスワード</h2>
          <input
            type="password"
            name="password"
            value={formData.password}
            onChange={handleChange}
            placeholder="Your Password"
          />
          <button onClick={prevStep}>戻る</button>
          <button onClick={() => console.log(formData)}>送信</button>
        </div>
      )}
    </div>
  );
}

これで、inputの数が増えてもhandleChange一つで対応可能になります!

まとめ

  • inputname属性を活用すると、1つのhandleChange関数で複数の状態更新に対応可能
  • 冗長なコードを減らし、保守性が高く、スケーラブルなフォーム実装ができる

このテクニックはReactでフォームを扱う際の定番パターンなので、ぜひ覚えておきましょう!

1
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?