React onChange事件处理多对象数组状态:如何更新不覆盖原有值
React数组类型状态不覆盖更新的实现方案
原代码存在的问题
- 错误使用
filter方法遍历,且更新状态时仅传入被修改的单个对象组成的数组,直接覆盖了原数组的其他所有项 - 更新状态时未保留原数组其他项,也没有保证匹配项的原有属性不被覆盖
- 输入框绑定的
value为title字段,但更新时修改的是job_title字段,二者不匹配会导致视图无法同步更新 - 遍历渲染列表项未添加
key属性,会触发React的渲染警告
优化后的实现
状态更新方法修正
const handleChange = (id, inputValue) => { // 使用函数式写法获取上一次的最新状态,避免闭包导致的状态过期 setEmployement(prevState => { // 遍历原数组返回完整新数组,保证所有未修改项完整保留 return prevState.map(emp => { // id不匹配的项原样返回,不做任何修改 if (emp.id !== id) return emp // id匹配的项先展开原有所有属性,再覆盖要修改的单个字段,保证原有属性不丢失 return { ...emp, title: inputValue } }) }) }
渲染逻辑修正
employement.map(singleEmp => ( <input key={singleEmp.id} type="text" value={singleEmp.title} onChange={(e) => handleChange(singleEmp.id, e.target.value)} /> ))
核心原理
- 状态更新的函数式写法可以直接获取上一次的最新状态,避免异步更新、闭包导致的状态过期问题
- 用
map遍历返回完整新数组,保证原数组中未修改的其他项完全保留不被覆盖 - 匹配到对应id的对象时,通过展开运算符
...emp保留对象所有原有属性,再覆盖需要修改的单个属性,保证对象内其他值不丢失 - 给列表项添加唯一
key属性,优化React的Diff渲染性能,避免渲染警告
内容的提问来源于stack exchange,提问作者M Ahmad
相关产品推荐
相关产品推荐

