React.js中setState更新过滤列表时误删最后一行如何解决?
问题根因
这个问题和setState逻辑无关,是React列表渲染时缺少唯一key导致的虚拟DOM diff异常。
你当前循环渲染表格行时没有给<tr>元素设置唯一key属性,React默认会用数组索引作为key。当你删除中间某一项后,后续所有元素的索引都会整体前移,React做虚拟DOM对比时会判定你只是删除了列表最后一项,就会出现「点击删中间行,界面显示删了最后一行」的异常,但此时你打印stateInitialData会发现state里的数据已经是正确过滤后的结果,只是界面渲染出了问题。
修复步骤
- 给每行数据增加唯一标识
不要用数组索引作为唯一标识,给每条行数据新增一个全局唯一的rowId字段,初始化和新增行时都要生成:
// 初始化数据时加rowId const initialData = [ { rowId: Date.now() + Math.random(), // 确保唯一即可,也可以用自增id、uuid等方案 customer_payor: list_customer_payor, bank: list_bank, bank_branch: list_bank_accounts, check_no: null, check_date: null, amount: null, remarks: list_remarks, }, // 剩余4条初始数据同理添加唯一rowId ] // 新增行逻辑里也要给新数据加rowId const AddInitialData = (e) => { e.preventDefault(); setStateInitialData([...stateInitialData, { rowId: Date.now() + Math.random(), customer_payor: list_customer_payor, bank: list_bank, bank_branch: list_bank_accounts, check_no: null, check_date: null, amount: null, remarks: list_remarks, }, // 剩余新增的行同理添加唯一rowId ]) }
- 给渲染的
<tr>元素绑定唯一key
修改map渲染逻辑,将rowId作为key属性的值,不要用循环索引:
stateInitialData.map((data, index) => { return ( <tr key={data.rowId}> {/* 原有表格单元格内容不变 */} <td style={{backgroundColor:'#FFFF',borderTopColor:'#FFFF'}}><DeleteOutlined onClick={(e) => RemoveEachRow(e,index)}/></td> </tr> ) })
内容的提问来源于stack exchange,提问作者DevGe
相关产品推荐
相关产品推荐

