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

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还未初始化(比如组件未挂载就调用)

快速修复步骤

  1. 确认apiRef已正确传递给DataGridPro组件
  2. 构建筛选模型时,严格遵循{ items: GridFilterItem[] }的结构
  3. 检查每个筛选规则的必填字段,确保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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 02:20:39