MUI X Data Grid传入getRowId仍提示行缺少唯一id报错
问题原因
报错由两个核心问题触发:
- 遍历Firestore返回的文档集合时,在循环内逐次调用
setRows更新状态:- 每次状态更新都会触发组件重渲染,DataGrid会在数据未完全加载的中间状态多次渲染,只要过程中出现id缺失、重复就会直接抛错
- React 18 严格模式下
useEffect会默认执行两次,这种逐次追加数组的写法会导致所有管理员数据被重复插入两次,直接造成id重复
- 存在潜在id缺失风险:如果admins集合中有任意文档未配置
email字段,对应行的id会是undefined,多个缺失email的文档会出现重复id,触发组件的id唯一性校验。
修复方案
不要在循环内逐次更新状态,先一次性遍历组装好所有行数据,再单次调用setRows完成状态更新,同时增加id兜底逻辑避免字段缺失导致的异常,修改后的useEffect代码如下:
useEffect(() => { const getAdmins = async () => { const adminsSnapshot = await getDocs(collection(db, "admins")); // 一次性组装所有行数据,避免循环内多次触发状态更新 const adminRows = adminsSnapshot.docs.map((doc) => { const data = doc.data(); return { // 优先使用email作为行id,email缺失时用Firestore自带的文档唯一id兜底,保证全局唯一 id: data.email || doc.id, name: data.name, email: data.email, roles: data.roles, isSuspended: data.isSuspended, lastUpdated: data.lastUpdated, updatedByEmail: data.updatedByEmail, }; }); setRows(adminRows); }; getAdmins(); }, []);
补充说明:你代码中配置的
getRowId={(row) => row.email}本身写法没有问题,但因为上述状态更新逻辑的缺陷,DataGrid在中间渲染阶段拿到的rows数组本身就存在重复/缺失id的问题,所以即使配置了getRowId依然会报错。使用上述一次性组装数据+id兜底的逻辑后,甚至可以省略手动配置的getRowId属性,因为行数据本身已经携带了唯一id字段。
内容的提问来源于stack exchange,提问作者Wambura
相关产品推荐
相关产品推荐

