MUI X Data Grid(Pro版)如何通过自定义组件设置筛选器
MUI X Data Grid Pro 自定义复选框筛选实现方案
一、是否该用setFilterModel方法?
是,这是官方推荐的自定义筛选控制方式,完全匹配你的需求场景。
二、「TypeError: Cannot read properties of undefined (reading 'length')」错误原因及解决办法
错误原因
这个报错基本都是因为传入setFilterModel的筛选模型格式不合法,常见场景:
- 没使用
items数组包裹筛选规则,直接传了单个对象或undefined - 某个筛选规则(
GridFilterItem)缺少field/operator等必填属性 - 筛选规则的
value字段为undefined,导致内部处理时读取length属性失败 - 调用
setFilterModel时apiRef.current还未初始化(比如组件未挂载就调用)
快速修复步骤
- 确认
apiRef已正确传递给DataGridPro组件 - 构建筛选模型时,严格遵循
{ items: GridFilterItem[] }的结构 - 检查每个筛选规则的必填字段,确保
field(列名)、operator(筛选操作符)存在,value不为undefined
三、完整实现步骤及代码示例
1. 初始化状态管理复选框勾选状态
用useState保存各个筛选选项的勾选情况:
import { useState } from 'react'; import { DataGridPro, useGridApiRef } from '@mui/x-data-grid-pro'; import Checkbox from '@mui/material/Checkbox'; import FormControlLabel from '@mui/material/FormControlLabel'; const MyGrid = () => { // 保存复选框勾选状态 const [filterStates, setFilterStates] = useState({ lettersTop10: false, lettersBottom10: false, numbersEven: false, numbersOdd: false, namesStartWithB: false, namesStartWithJ: false, }); // 获取Data Grid的api引用 const apiRef = useGridApiRef();
2. 编写筛选模型构建函数
根据复选框的勾选状态,动态生成合法的筛选模型:
// 处理复选框变化,更新筛选模型 const handleFilterToggle = (key, checked) => { const newFilterStates = { ...filterStates, [key]: checked }; setFilterStates(newFilterStates); const filterItems = []; // 处理Letters列筛选:前10/后10位互斥 if (newFilterStates.lettersTop10) { filterItems.push({ field: 'Letters', operator: 'in', value: ['A','B','C','D','E','F','G','H','I','J'], }); } else if (newFilterStates.lettersBottom10) { filterItems.push({ field: 'Letters', operator: 'in', value: ['Q','R','S','T','U','V','W','X','Y','Z'], }); } // 处理Numbers列筛选:偶数/奇数互斥 if (newFilterStates.numbersEven) { filterItems.push({ field: 'Numbers', operator: 'custom', // 自定义筛选逻辑,判断是否为偶数 getApplyFilterFn: () => (value) => value % 2 === 0, }); } else if (newFilterStates.numbersOdd) { filterItems.push({ field: 'Numbers', operator: 'custom', getApplyFilterFn: () => (value) => value % 2 === 1, }); } // 处理Names列筛选:支持多条件组合(B/J开头同时生效) const nameFilters = []; if (newFilterStates.namesStartWithB) { nameFilters.push({ field: 'Names', operator: 'startsWith', value: 'B', }); } if (newFilterStates.namesStartWithJ) { nameFilters.push({ field: 'Names', operator: 'startsWith', value: 'J', }); } // 多个Names筛选条件用OR逻辑组合 if (nameFilters.length > 0) { filterItems.push({ logicOperator: 'or', filters: nameFilters, }); } // 应用筛选模型 apiRef.current.setFilterModel({ items: filterItems }); };
3. 渲染侧边栏复选框与Data Grid
return ( <div style={{ display: 'flex', height: 600 }}> {/* 侧边栏筛选面板 */} <div style={{ width: 250, padding: 16, borderRight: '1px solid #eee' }}> <h3>Letters筛选</h3> <FormControlLabel control={<Checkbox checked={filterStates.lettersTop10} onChange={(e) => handleFilterToggle('lettersTop10', e.target.checked)} />} label="前10位字母" /> <FormControlLabel control={<Checkbox checked={filterStates.lettersBottom10} onChange={(e) => handleFilterToggle('lettersBottom10', e.target.checked)} />} label="后10位字母" /> <h3 style={{ marginTop: 24 }}>Numbers筛选</h3> <FormControlLabel control={<Checkbox checked={filterStates.numbersEven} onChange={(e) => handleFilterToggle('numbersEven', e.target.checked)} />} label="偶数" /> <FormControlLabel control={<Checkbox checked={filterStates.numbersOdd} onChange={(e) => handleFilterToggle('numbersOdd', e.target.checked)} />} label="奇数" /> <h3 style={{ marginTop: 24 }}>Names筛选</h3> <FormControlLabel control={<Checkbox checked={filterStates.namesStartWithB} onChange={(e) => handleFilterToggle('namesStartWithB', e.target.checked)} />} label="以B开头" /> <FormControlLabel control={<Checkbox checked={filterStates.namesStartWithJ} onChange={(e) => handleFilterToggle('namesStartWithJ', e.target.checked)} />} label="以J开头" /> </div> {/* Data Grid主体 */} <DataGridPro apiRef={apiRef} columns={yourColumns} // 替换为你的列配置 rows={yourRows} // 替换为你的数据 disableColumnFilter // 可选:关闭默认列筛选菜单,避免冲突 autoHeight /> </div> ); }; export default MyGrid;
四、额外注意事项
- 互斥筛选(比如Letters的前10/后10):在构建
filterItems时用else if确保同一列只有一个筛选规则生效 - 自定义筛选逻辑:用
getApplyFilterFn实现复杂判断(比如奇偶性),此时operator设为custom即可 - 多条件组合:同一列的多个筛选规则可以用
logicOperator: 'or'/'and'包裹,实现组合筛选
内容的提问来源于stack exchange,提问作者Moshe
相关产品推荐
相关产品推荐

