如何在MUI X Data Grid自定义过滤器中设置值触发onFilterModelChange?
解决MUI X Data Grid自定义过滤器设置过滤值及
columnVisibilityModel报错问题 错误原因
直接调用api.setState修改filterModel会绕过Data Grid内部状态管理逻辑,破坏状态依赖关系,导致columnVisibilityModel等内部状态未被正确初始化/更新,从而触发报错。必须使用官方提供的状态更新方法。
完整实现代码
父组件(DataGrid配置)
import { DataGrid, GridColDef } from '@mui/x-data-grid'; import DateRangeFilter from './DateRangeFilter'; const columns: GridColDef[] = [ { field: 'id', headerName: 'ID', width: 90 }, { field: 'name', headerName: 'Name', width: 150 }, { field: 'date', headerName: 'Date', width: 200, // 自定义过滤操作符 filterOperators: [ { value: 'dateRange', label: 'Date Range', // 本地过滤逻辑(服务端过滤时可忽略) getApplyFilterFn: (filterItem) => { if (!filterItem.value || filterItem.value.length !== 2) return null; const [start, end] = filterItem.value; return (row) => { const rowDate = new Date(row.date); return rowDate >= start && rowDate <= end; }; }, }, ], filter: DateRangeFilter, // 指定自定义过滤器组件 }, ]; const rows = [ { id: 1, name: 'John Doe', date: '2024-01-15' }, { id: 2, name: 'Jane Smith', date: '2024-02-20' }, { id: 3, name: 'Bob Brown', date: '2024-03-10' }, ]; export default function DataGridDemo() { const handleFilterModelChange = (model) => { // 此处获取过滤模型,用于后端数据请求 console.log('过滤条件变更:', model); }; return ( <div style={{ height: 400, width: '100%' }}> <DataGrid rows={rows} columns={columns} filterMode="server" // 开启服务端过滤模式 onFilterModelChange={handleFilterModelChange} initialState={{ filter: { filterModel: { items: [] }, }, }} /> </div> ); }
自定义过滤器组件(DateRangeFilter)
import { useGridApiContext, useGridFilterItemProps } from '@mui/x-data-grid'; import { DateRangePicker } from 'rsuite'; import 'rsuite/dist/rsuite.min.css'; export default function DateRangeFilter() { const { item, applyFilter } = useGridFilterItemProps(); const api = useGridApiContext(); const handleDateChange = (value) => { // 获取当前过滤模型,合并新的日期范围过滤条件 const currentFilterModel = api.getFilterModel(); const existingItemIndex = currentFilterModel.items.findIndex( f => f.field === item.field ); let newItems = [...currentFilterModel.items]; if (existingItemIndex !== -1) { // 更新已有列的过滤条件 newItems[existingItemIndex] = { ...item, value }; } else { // 添加新的过滤条件 newItems.push({ field: item.field, operator: 'dateRange', value }); } // 使用官方方法更新过滤模型,避免直接修改state报错 api.setFilterModel({ ...currentFilterModel, items: newItems }); // 触发过滤应用 applyFilter(); }; return ( <DateRangePicker value={item.value || []} onChange={handleDateChange} format="yyyy-MM-dd" style={{ padding: 8, width: '100%' }} /> ); }
关键说明
- 使用
api.setFilterModel替代直接调用api.setState,这是Data Grid官方提供的过滤模型更新方法,会正确处理内部状态依赖,避免报错。 - 通过
useGridFilterItemProps获取当前列的过滤项信息和applyFilter方法,更规范地处理单列过滤更新。 - 合并现有过滤条件,避免覆盖其他列的过滤设置。
- 开启
filterMode="server",适配后端数据请求场景,前端仅负责传递过滤条件,由后端处理数据筛选。
内容的提问来源于stack exchange,提问作者Nju
相关产品推荐
相关产品推荐

