React中如何按ID向嵌套的inspections数组添加元素
问题:React useState 更新嵌套数组错误,新元素被添加到外层数组而非目标嵌套数组
我用React的useState Hook更新现有数组,想按ID找到对应元素,往它内部的inspections数组添加新检查项,但当前代码把新元素加到了data数组末尾,而非目标嵌套数组中。
初始数据
export const data = [ { id: Math.floor(Math.random() * 999999), description: "", type: "car", inspections: [ { id: Math.floor(Math.random() * 999999), name: `Inspection${Math.floor(Math.random() * 999999)}`, type: "any", }, ], }, ];
当前更新函数
const [dataArray, setDataArray] = useState(data); const [inspection, setInspection] = useState(""); function handleInspection(id) { setDataArray((prevState) => [ ...prevState, { id: id, description: "", type: "", inspections: [ { id: Math.floor(Math.random() * 999999), name: `Inspection${Math.floor(Math.random() * 999999)}`, type: inspection, }, ], }, ]); }
渲染与交互代码
{dataArray.map((vehicles) => { return ( <div> <div key={vehicles.id}>vehicle type:{vehicles.type}</div> <ul> {vehicles.inspections.map((inspection) => { return <li>type: {inspection.type}</li>; })} lorry <input name="option" type="radio" className="form-control" autoFocus={true} onChange={() => setInspection("Lorry")} aria-label="Enter the title of your todo" placeholder="Enter a new todo" value={inspection} /> van <input name="option" type="radio" className="form-control" onChange={() => setInspection("Van")} autoFocus={true} aria-label="Enter the title of your todo" placeholder="Enter a new todo" value={inspection} /> car <input name="option" type="radio" className="form-control" onChange={() => setInspection("Car")} autoFocus={true} aria-label="Enter the title of your todo" placeholder="Enter a new todo" value={inspection} /> any <input name="option" type="radio" className="form-control" onChange={() => setInspection("Any")} autoFocus={true} aria-label="Enter the title of your todo" placeholder="Enter a new todo" value={inspection} /> </ul> <button className="addButton" onClick={() => handleInspection(vehicles.id)} > Add Inspection </button> </div> ); })}
问题原因与修正方案
问题根源
当前handleInspection函数只是把新对象直接追加到prevState数组末尾,完全没有定位到目标元素并更新其内部的inspections数组,这才导致新元素出现在外层数组。
修正后的更新函数
需要遍历数组找到对应ID的元素,复制该元素并更新其inspections数组,同时保留其他元素不变:
function handleInspection(id) { setDataArray((prevState) => prevState.map(item => { // 匹配到目标元素时进行更新 if (item.id === id) { return { ...item, // 复制原元素的所有属性 inspections: [ ...item.inspections, // 保留原有检查项 { id: Math.floor(Math.random() * 999999), name: `Inspection${Math.floor(Math.random() * 999999)}`, type: inspection, } ] }; } // 非目标元素直接返回原对象 return item; }) ); }
额外优化点
- 修复单选按钮的选中状态:每个单选按钮的
value应设为对应类型值,同时通过checked属性关联inspection状态,确保选中状态正确显示:
// 以lorry选项为例,其余选项同理 <input name="option" type="radio" className="form-control" onChange={() => setInspection("Lorry")} aria-label="Select Lorry inspection type" value="Lorry" checked={inspection === "Lorry"} />
- 移除所有单选按钮的
autoFocus属性,避免每次渲染自动聚焦影响用户操作。
内容的提问来源于stack exchange,提问作者rednate95
相关产品推荐
相关产品推荐

