React Material Table更新删除报错:重复key及删除无响应问题排查
React Material Table 更新/删除操作异常问题修复
问题根源分析
你的代码存在三个关键问题,导致删除无响应、更新触发key重复警告:
1. 删除操作依赖不可靠的内部索引
onRowDelete中使用selectedRow.tableData.id作为数组索引是错误的——tableData.id是Material Table内部维护的行位置标记,当数据增删后,这个标记和数组实际索引会出现不匹配,导致删除操作无法定位到正确的行。
2. 更新操作存在变量名错误与逻辑错误
onRowUpdate里:
- 变量名写错:声明了
updatedRow却使用未定义的updatedRows - 赋值逻辑错误:将整个数组赋值给单个元素,正确逻辑应该是把更新后的行数据替换到对应位置
- 同样依赖了不可靠的
oldRow.tableData.id作为索引
3. 添加行时ID生成逻辑易重复
使用Math.floor(Math.random() * 100)生成ID,极易和现有数据的ID冲突,Material Table以id作为行的唯一key,重复ID就会触发"两个子元素key相同"的警告。
修正后的完整代码
import React, { useState } from 'react'; import MaterialTable from '@material-table/core'; import { emplist as RoomInfo } from './data/emplist'; function App() { const [data, setData] = useState(RoomInfo); // 生成绝对唯一的ID:取现有数据最大ID+1 const generateUniqueId = () => { const maxId = data.length ? Math.max(...data.map(item => item.id)) : 0; return maxId + 1; }; const columns = [ { title: 'ID', field: 'id', editable: false }, // 设置ID不可编辑,避免手动修改引发重复 { title: 'Floor Name', field: 'FloorName' }, { title: 'Building Name', field: 'BuildingName' }, { title: 'Room Code', field: 'RoomCode' }, { title: 'Room Name', field: 'RoomName' }, { title: 'Room Area', field: 'RoomArea' }, { title: 'Room Perimeter', field: 'RoomPerimeter' }, { title: 'Room Height', field: 'RoomHeight' }, ]; return ( <MaterialTable title="Editable Preview" columns={columns} data={data} editable={{ onRowAdd: (newRow) => new Promise((resolve) => { const updatedRows = [ ...data, { id: generateUniqueId(), ...newRow }, ]; setTimeout(() => { setData(updatedRows); resolve(); }, 2000); }), onRowDelete: (selectedRow) => new Promise((resolve) => { // 通过数据唯一ID筛选,彻底避免索引不匹配问题 const updatedRows = data.filter(row => row.id !== selectedRow.id); setTimeout(() => { setData(updatedRows); resolve(); }, 1000); }), onRowUpdate: (newData, oldData) => new Promise((resolve) => { // 通过唯一ID定位并替换行数据 const updatedRows = data.map(row => row.id === oldData.id ? { ...newData } : row ); setTimeout(() => { setData(updatedRows); resolve(); }, 1000); }), }} options={{ actionsColumnIndex: -1, addRowPosition: 'first', }} /> ); } export default App;
关键修复点说明
- 删除操作:改用
filter方法通过唯一ID筛选数据,彻底规避索引不匹配问题 - 更新操作:用
map方法根据ID匹配替换行数据,修正变量名错误 - ID生成:通过现有数据的最大ID+1生成新ID,确保绝对唯一;同时设置ID列不可编辑,防止手动修改引发重复
- 冗余清理:删除了未使用的
Component、useEffect、axios导入
内容的提问来源于stack exchange,提问作者Fikret AKBAŞ
相关产品推荐
相关产品推荐

