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

如何为react-data-grid的列添加筛选与排序功能

如何在react-data-grid中实现列筛选与排序功能

我尝试多日仍无法在adazzle的react-data-grid库中实现表格列的可筛选与可排序功能,以下是我的原始代码,求熟悉该库的开发者帮忙指出问题并给出解决方案:

import React, { useState, useEffect } from "react";
import ReactDataGrid from "react-data-grid";
//import {  Toolbar, Filters } from "react-data-grid-addons";

function Data() {
  const [columns, setColumns] = useState([]);
  const [rows, setRows] = useState([]);

  useEffect(() => {

    const defaultComponentProperties = {
      resizable: true,
      filterable: true,
      sortable: true,
    };
    // Fetch grid configuration
    fetch('../local-json/gridConfig.json')
      .then(response => response.json())
      .then(myConfig => {
        myConfig = myConfig.map(c => ({...c, ...defaultComponentProperties}))
        setColumns(myConfig)
      })
      .catch(error => {
        console.error('Error fetching grid configuration:', error);
      })

    // Fetch grid data
    fetch('../local-json/gridData.json')
      .then(response => response.json())
      .then(myData => {
        setRows(myData);
      })
      .catch(error => {
        console.error('Error fetching grid data:', error);
      });
  }, [])

  return (
    <div className="grid-container">
      <ReactDataGrid
        columns={columns}
        rowGetter={i => rows[i]}
        rowsCount={rows.length}
        minHeight={300}
        onColumnResize={(idx, width) =>
          console.log(`Column ${idx} has been resized to ${width}`)
        }
        enableCellSelect
      />
    </div>
  );
}

export default Data;

解决方案:完整修改后的代码

import React, { useState, useEffect, useMemo } from "react";
import ReactDataGrid from "react-data-grid";
import { Toolbar, Filters } from "react-data-grid-addons";

function Data() {
  const [columns, setColumns] = useState([]);
  const [rawRows, setRawRows] = useState([]);
  const [filterValues, setFilterValues] = useState({});
  const [sortColumn, setSortColumn] = useState(null);
  const [sortDirection, setSortDirection] = useState(null);

  useEffect(() => {
    const defaultComponentProperties = {
      resizable: true,
      filterable: true,
      sortable: true,
    };
    // Fetch grid configuration
    fetch('../local-json/gridConfig.json')
      .then(response => response.json())
      .then(myConfig => {
        const updatedColumns = myConfig.map(c => ({
          ...c,
          ...defaultComponentProperties,
          // 根据列数据类型指定筛选器,示例为文本筛选器,可替换为NumberFilter等
          filterRenderer: Filters.TextFilter
        }));
        setColumns(updatedColumns);
      })
      .catch(error => {
        console.error('Error fetching grid configuration:', error);
      });

    // Fetch grid data
    fetch('../local-json/gridData.json')
      .then(response => response.json())
      .then(myData => {
        setRawRows(myData);
      })
      .catch(error => {
        console.error('Error fetching grid data:', error);
      });
  }, []);

  // 缓存筛选和排序后的结果,避免重复计算
  const processedRows = useMemo(() => {
    let result = [...rawRows];

    // 应用筛选逻辑
    if (Object.keys(filterValues).length > 0) {
      result = result.filter(row => {
        return Object.entries(filterValues).every(([columnKey, value]) => {
          if (!value) return true;
          const rowValue = row[columnKey];
          return String(rowValue).toLowerCase().includes(value.toLowerCase());
        });
      });
    }

    // 应用排序逻辑
    if (sortColumn && sortDirection) {
      result = [...result].sort((a, b) => {
        const valA = a[sortColumn.key];
        const valB = b[sortColumn.key];
        if (typeof valA === 'string' && typeof valB === 'string') {
          return sortDirection === 'ASC' ? valA.localeCompare(valB) : valB.localeCompare(valA);
        }
        return sortDirection === 'ASC' ? valA - valB : valB - valA;
      });
    }

    return result;
  }, [rawRows, filterValues, sortColumn, sortDirection]);

  // 排序触发回调
  const handleSort = (sortColumn, sortDirection) => {
    setSortColumn(sortColumn);
    setSortDirection(sortDirection);
  };

  // 筛选条件变更回调
  const handleFilterChange = (filter) => {
    setFilterValues(prev => ({
      ...prev,
      [filter.column.key]: filter.filterTerm
    }));
  };

  // 清空所有筛选条件
  const clearFilters = () => {
    setFilterValues({});
  };

  return (
    <div className="grid-container">
      <ReactDataGrid
        columns={columns}
        rowGetter={i => processedRows[i]}
        rowsCount={processedRows.length}
        minHeight={300}
        onColumnResize={(idx, width) =>
          console.log(`Column ${idx} has been resized to ${width}`)
        }
        enableCellSelect
        // 绑定排序与筛选回调
        onSort={handleSort}
        onFilterChange={handleFilterChange}
        // 添加筛选工具栏UI
        toolbar={<Toolbar enableFiltering />}
        clearFilters={clearFilters}
      />
    </div>
  );
}

export default Data;

关键修改点说明

  1. 导入核心组件

    • 取消注释import { Toolbar, Filters } from "react-data-grid-addons",这两个组件是实现筛选UI和基础筛选逻辑的必要依赖。
  2. 拆分数据状态

    • 将原rows拆分为rawRows(存储原始接口数据)和processedRows(存储经过筛选、排序后的最终渲染数据),避免直接修改原始数据导致状态混乱。
  3. 新增状态管理

    • filterValues:存储各列的筛选关键词
    • sortColumn/sortDirection:存储当前排序的目标列和排序方向(升序/降序)
  4. 数据处理逻辑

    • 使用useMemo缓存处理后的数据,仅在依赖项变化时重新计算,提升性能
    • 先执行筛选:遍历所有筛选条件,保留符合条件的行数据
    • 再执行排序:根据当前排序配置对筛选后的行进行排序,兼容字符串和数字类型的排序逻辑
  5. 列配置补充

    • 为列添加filterRenderer属性,指定该列使用的筛选器类型(如文本筛选器、数字筛选器,需匹配列数据类型)
  6. 绑定交互回调

    • 为表格组件绑定onSort和onFilterChange回调,同步更新筛选、排序状态
    • 加入toolbar={<Toolbar enableFiltering />}显示筛选操作的UI界面,添加clearFilters方法实现一键清空筛选

内容的提问来源于stack exchange,提问作者EvJ

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 20:23:13