JavaScript, React.js, JSX: 複数の入力要素を1つのonChangeハンドラーで識別する
問題
React.jsで複数の入力要素(例えば、複数のテキストフィールドやチェックボックス)があり、それぞれに対して同じonChangeハンドラーを適用したい場合、どのように入力要素を区別して適切な処理を行うことができるでしょうか?
解決方法
- e.target.name属性を利用
- 各入力要素に固有の
name
属性を設定します。 - onChangeハンドラー内で
e.target.name
プロパティをチェックすることで、どの入力要素が変更されたかを判断できます。
- 各入力要素に固有の
import React, { useState } from 'react';
function MyForm() {
const [formData, setFormData] = useState({
firstName: '',
lastName: '',
email: '',
});
const handleChang e = (e) => {
const { name, value } = e.target;
setFormData((prevData) => ({
...prevData,
[name]: value,
}));
};
return (
< form>
<input
type="text"
name="firstName"
value={formData.firstName}
onChange={handleChange}
/>
<input
type="text"
name="lastName"
value={formData.lastName}
onChange={handleChange}
/>
<inp ut
type="email"
name="email"
value={formData.email}
onChange={handleC hange}
/>
</form>
);
}
- どの属性を使用するかは、プロジェクトの構造や要件に応じて選択できます。
id
属性は主にCSSセレクターやJavaScriptでの要素参照に使用されます。name
属性は通常、フォームの送信時にデータを送信するために使用されます。
React.js: 複数の入力要素を1つのonChangeハンドラーで識別する
例1: name属性を利用
import React, { useState } from 'react';
function MyForm() {
const [formData, setFormData] = useState({
firstName: '',
lastName: '',
email: '',
});
const handleChang e = (e) => {
const { name, value } = e.target;
setFormData((prevData) => ({
...prevData,
[name]: value,
}));
};
return (
< form>
<input
type="text"
name="firstName"
value={formData.firstName}
onChange={handleChange}
/>
<input
type="text"
name="lastName"
value={formData.lastName}
onChange={handleChange}
/>
<inp ut
type="email"
name="email"
value={formData.email}
onChange={handleC hange}
/>
</form>
);
}
解説
setFormData
関数を使用して、変更された入力要素の値をformData
状態に更新します。name
属性は各入力要素に固有の識別子を与えます。
例2: id属性を利用
import React, { useState } from 'react';
function MyForm() {
const [formData, setFormData] = useState({
firstName: '',
lastName: '',
email: '',
});
const handleChang e = (e) => {
const { id, value } = e.target;
setFormData((prevData) => ({
...prevData,
[id]: value,
}));
};
return (
<form>
<input
type="text"
id="firstName"
value={formData.firstName}
onChange={handleChange}
/>
<input
type="text"
id="lastName"
value={formData.lastName}
onChange={handleChange}
/>
<input
type="email"
id="email"
value={formData.email}
onChange={handleChange}
/>
</form>
);
}
例3: className属性を利用
import React, { useState } from 'react';
function MyForm() {
const [formData, setFormData] = useState({
firstName: '',
lastName: '',
email: '',
});
const handleChang e = (e) => {
const { className, value } = e.target;
setFormData((prevData) => ({
...prevData,
[className]: value,
}));
};
return (
<form>
<input
type="text"
className="firstName"
value={formData.firstName}
onChange={handleChange}
/>
<input
type="text"
className="lastName"
value={formData.lastName}
onChange={handleChange}
/>
<input
type="email"
className="email"
value={formData.email}
onChange={handleChange}
/>
</form>
);
}
className
属性は各入力要素に固有のクラス名を与えます。
共通点
setFormData
関数を使用して、状態を更新することで、入力要素の値を反映しています。- 3つの例すべてにおいて、
onChange
ハンドラー内でe.target
プロパティを使用して、変更された入力要素の情報を取得しています。
import React, { useState } from 'react';
function MyForm() {
const [formData, setFormData] = useState({
firstName: '',
lastName: '',
email: '',
});
const handleChang e = (name) => (e) => {
setFormData((prevData) => ({
...prevData,
[name]: e.target.value,
}));
};
return (
<form>
<input
type="text"
name="firstName"
value={formData.firstName}
onChange={handleChange('firstName')}
/>
{/* ... */}
</form>
);
}
- 各入力要素の
onChange
属性に、handleChange
関数を呼び出して名前を渡すことで、入力要素を識別します。 handleChange
関数を、入力要素の名前を受け取る関数と、イベントオブジェクトを受け取る関数のネストとして定義します。
Ref
import React, { useState, useRef } from 'react';
function MyForm() {
const [formData, setFormData] = useState({
firstName: '',
lastName: '',
email: '',
});
const firstNameRef = useRef(null);
const lastNameRef = useRef(null);
const emailRef = useRef(null);
const handleChange = () => {
setFormData({
firstName: firstNameRef.current.value,
lastName: lastNameRef.current.value,
email: emailRef.current.value,
});
};
return (
<form>
<input
type="text"
ref={firstNameRef}
value={formData.firstName}
onChange={handleChange}
/>
{/* ... */}
</form>
);
}
handleChange
関数内で、ref
を使用して要素の値を取得し、状態を更新します。- 各入力要素に
ref
属性を付けて、その要素への参照を保持します。
カスタムフック
import React, { useState, useCallback } from 'react';
function useInput(initialValue) {
const [value, setValue] = useState(initialValue);
const handleChange = useCallback((e) => {
setValue(e.target.value);
}, []);
return [value, handleChange];
}
function MyForm() {
const [firstName, handleFirstNameChange] = useInput('');
const [lastName, handleLastNameChange] = useInput('');
const [email, handleEmailChange] = useI nput('');
// ...
}
- 各入力要素で
useInput
を使用し、状態管理と変更ハンドラーを共通化します。 - カスタムフック
useInput
を作成し、入力値と変更ハンドラーを返します。
選択基準
- 再利用性
カスタムフックはコードの再利用性が高くなります。 - 複雑さ
Refは複雑になる可能性があり、慎重に使用すべきです。 - シンプルさ
関数型コンポーネントと解体構文は最もシンプルで直感的な方法です。
javascript reactjs jsx