はじめに
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
一つで対応可能になります!
まとめ
-
input
のname
属性を活用すると、1つのhandleChange
関数で複数の状態更新に対応可能 - 冗長なコードを減らし、保守性が高く、スケーラブルなフォーム実装ができる
このテクニックはReactでフォームを扱う際の定番パターンなので、ぜひ覚えておきましょう!