You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 11:50:19