表单数组索引增删异常:移除指定项却删除最后一项
问题原因及解决办法
问题根源
你遇到的问题是React列表渲染的key使用不当导致的。当用index或者重复/不稳定的值作为列表项的key时,React更新列表时会复用现有组件而非重新渲染,哪怕数据已经正确更新,视觉上也会出现删除项和预期不符的情况。另外你维护了formData和wkArray两个状态,容易出现状态不同步的问题,进一步加剧渲染异常。
具体修复步骤
1. 给每个表单项添加唯一ID,用ID作为key
修改初始化状态,给每个wk对象加上唯一标识(示例用时间戳生成,也可以用uuid等):
const [formData, setFormData] = useState({ wk: [ { id: Date.now(), // 初始唯一ID companyName: "", reasonForChange: "", role: "" } ] });
2. 移除冗余的wkArray状态
直接用formData.wk的长度控制表单数量,避免状态不同步:
- 添加表单时,往
formData.wk中推入带新ID的对象:
const addWorkExperience = () => { setFormData(prev => ({ ...prev, wk: [...prev.wk, { id: Date.now(), companyName: "", reasonForChange: "", role: "" }] })); };
- 删除表单时,根据ID过滤数组(比用索引更可靠):
const removeWorkExperience = (id) => { setFormData(prev => ({ ...prev, wk: prev.wk.filter(item => item.id !== id) })); };
3. 渲染列表时用唯一ID作为key
{formData.wk.map(item => ( <div key={item.id} className="form-group"> <input value={item.companyName} onChange={(e) => handleInputChange(item.id, 'companyName', e.target.value)} placeholder="公司名称" /> <input value={item.reasonForChange} onChange={(e) => handleInputChange(item.id, 'reasonForChange', e.target.value)} placeholder="变更原因" /> <input value={item.role} onChange={(e) => handleInputChange(item.id, 'role', e.target.value)} placeholder="职位" /> <button onClick={() => removeWorkExperience(item.id)}>删除</button> </div> ))}
4. 修改输入框的 onChange 逻辑
通过ID定位要修改的项,更新对应字段的值:
const handleInputChange = (id, field, value) => { setFormData(prev => ({ ...prev, wk: prev.wk.map(item => item.id === id ? {...item, [field]: value} : item ) })); };
这样修改后,React能正确识别每个列表项,删除操作的视觉效果会和数据更新保持一致,不会再出现删错项的问题。
内容的提问来源于stack exchange,提问作者Tejendra Singh Rajawat
相关产品推荐
相关产品推荐

