Reactの学習のために簡易なメモアプリをつくっているとこのようなことになってしまいました。
原因
mapメソッドを使用してメモ入力用のコンポーネントを生成しており、生成された全てのコンポーネントで同じ変数(name)がvalueとして使用されているため、このような問題が発生していることがわかりました。
page.js
export default function Home() {
const [name, setName] = useState('');
const handleInputChange = async (e, id) => {
const { name, value } = e.target;
setName(value);
//データベースへの送信
};
//略
return (
//略
<tbody>
{data && Array.isArray(data) && data.map(item => (
//このvalue={name}の部分
<input type="text" name="name" value={name} onChange={(e) => handleInputChange(e, item.id)}></input>
//略
))}
</tbody>
//略
);
}
解決策
ローカルステートで管理する
ローカルステートとは、Reactコンポーネント内で管理される状態(state)のことを指します。コンポーネントが自身の状態を持ち、その状態を変更することでUIを更新する仕組みです。
今回は、<input>
タグを含む子コンポーネントを作成し、それぞれのコンポーネントごとにuseState
を設定する方法を採用しました。
実装
NameBox.js
import { useState, useEffect } from "react";
import styles from './Table.module.css'
const NameBox = ({ initialValue, onChange}) => {
const [name, setName] = useState('');
useEffect(() => {
setName(initialValue);
}, [initialValue]);
const handleChange = (e) => {
const newValue = e.target.value;
setName(newValue);
onChange(e);
};
return(
<input type="text" name="name" value={name} onChange={handleChange}></input>
)
}
export default NameBox;
このコンポーネントはinitialValue
とonChange
という2つのプロパティを受け取り、onChange
イベントハンドラーとして使用されるhandleChange関数内で親コンポーネントに変更を通知するためにonChange
を呼び出します。
page.js
<NameBox initialValue={item.name} onChange={(e) => handleInputChange(e, item.id)}/>
作成したコンポーネントを呼び出しそれぞれプロパティを設定します。
結果
これによりそれぞれの入力ボックスに入力を行うことができました。