如何修复React MUI DataGrid中Id未定义的筛选器错误
问题:MUI DataGrid singleSelect列筛选报错及功能需求
问题现象
使用MUI DataGrid的singleSelect列时,数据显示和编辑均正常,但点击列筛选菜单项时触发以下错误:
Cannot read properties of undefined (reading 'id')
经排查,错误原因是筛选逻辑尝试从valueOptions中读取id属性,但传入值为undefined。
现有实现代码
const { PartGroups, hasPartGroupsUpdate } = useAppSelector((state) => state.partGroups); const [partGroups, setPartGroups] = useState<{id: number, description: string}[]>([{id: 0, description: '[Blank]'}]); const columns: GridColDef[] = [ { field: 'PartId', headerName: 'Part Id', width: 70, type: 'number', valueFormatter: ({ value }) => value }, { field: 'PartGroupId', headerName: 'Part Group', width: 200, type: 'singleSelect', valueGetter: (params) => params.row.PartGroupId !== undefined && params.row.PartGroupId !== null ? params.row.PartGroupId : 0, getOptionValue: (value: any) => value.id, getOptionLabel: (value: any) => value.description, valueOptions: (params) => partGroups, editable: true, }, { field: 'Description', headerName: 'Description', flex: 1, minWidth: 250 }, { field: 'DateLastUpdated', headerName: 'Last Updated', width: 160, valueFormatter: ({ value }) => moment(value).format("YYYY-MM-DD HH:mm:ss") }, ]; useEffect(() => { console.log(PartGroups) let newPartGroups:{id: number, description: string}[] = [{id: 0, description: '[Blank]'}]; const tempPartGroups = PartGroups.map((partGroup: PartGroupExt) => { return {id: partGroup.PartGroupId, description: partGroup.PartGroupName} }) newPartGroups = [...newPartGroups, ...tempPartGroups]; setPartGroups(newPartGroups); }, [PartGroups])
完整错误栈
Cannot read properties of undefined (reading 'id') TypeError: Cannot read properties of undefined (reading 'id') at getOptionValue (http://localhost:3000/main.ff56c9973bbd0507b366.hot-update.js:163:36) at getValueFromValueOptions (http://localhost:3000/static/js/bundle.js:87101:10) at http://localhost:3000/static/js/bundle.js:86603:94 at commitHookEffectListMount (http://localhost:3000/static/js/bundle.js:144267:30) at commitPassiveMountOnFiber (http://localhost:3000/static/js/bundle.js:145760:17) at commitPassiveMountEffects_complete (http://localhost:3000/static/js/bundle.js:145732:13) at commitPassiveMountEffects_begin (http://localhost:3000/static/js/bundle.js:145722:11) at commitPassiveMountEffects (http://localhost:3000/static/js/bundle.js:145712:7) at flushPassiveEffectsImpl (http://localhost:3000/static/js/bundle.js:147597:7) at flushPassiveEffects (http://localhost:3000/static/js/bundle.js:147549:18)
补充说明
- 采用服务端分页、排序和筛选方案
- Part Group字段非必填,允许为null,因此通过
valueGetter将null/undefined值映射为0,对应[Blank]选项
待解决问题
- 如何让筛选器正常访问
partGroups数据,避免上述报错? - 能否通过
valueSetter实现:选择0对应的[Blank]选项时,将PartGroupId设为null?
更新记录
- 尝试将
partGroups改为{value, label}结构并移除getOptionValue/getOptionLabel后功能正常,但希望保留自定义属性实现 - 搭建测试环境后出现新错误:需为筛选器设置key
- 尚未定位到问题细节,未解决
解决方案
问题1:修复筛选器访问partGroups报错
报错核心是getOptionValue被传入undefined值,需增加空值判断,同时优化valueOptions的传递方式:
// 为getOptionValue/getOptionLabel增加空值兜底 getOptionValue: (value: any) => value?.id ?? 0, getOptionLabel: (value: any) => value?.description ?? '[Blank]', // 直接传入数组而非函数(无需动态依赖参数时) valueOptions: partGroups,
确保partGroups在初始化和更新时始终是完整数组,避免出现undefined项。
问题2:通过valueSetter将[Blank]映射为null
在列配置中添加valueSetter,判断选中值为0时返回null:
valueSetter: (params) => { params.row.PartGroupId = params.value === 0 ? null : params.value; return true; // 通知DataGrid值已更新 },
修改后的完整列配置
{ field: 'PartGroupId', headerName: 'Part Group', width: 200, type: 'singleSelect', valueGetter: (params) => params.row.PartGroupId ?? 0, valueSetter: (params) => { params.row.PartGroupId = params.value === 0 ? null : params.value; return true; }, getOptionValue: (value: any) => value?.id ?? 0, getOptionLabel: (value: any) => value?.description ?? '[Blank]', valueOptions: partGroups, editable: true, },
服务端筛选适配(额外优化)
因为使用服务端筛选,需在传递筛选参数时将0替换为null:
const handleFilterChange = (model: GridFilterModel) => { const adjustedModel = { ...model }; const partGroupFilter = adjustedModel.items.find(item => item.field === 'PartGroupId'); if (partGroupFilter && partGroupFilter.value === 0) { partGroupFilter.value = null; } // 将adjustedModel发送到后端执行筛选 }; // 在DataGrid组件中绑定回调 <DataGrid ... onFilterModelChange={handleFilterChange} />
内容的提问来源于stack exchange,提问作者Hayden
相关产品推荐
相关产品推荐

