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

Ag Grid点击行重置agSetColumnFilter问题求助

解决React中Ag Grid的agSetColumnFilter点击行后重置问题

问题现象

  • 使用agSetColumnFilter完成筛选后,点击表格行,过滤器会被重置,所有行恢复显示
  • 触发该行为的onCellClicked仅用于更新React状态(调用setDrawerOpen),未对过滤器做任何修改
  • 仅agSetColumnFilter受影响,其他过滤器无此问题
  • 已尝试添加apply: true, newRowsAction: "keep"、设置deltaRowDataMode=true,均未解决

原因分析

组件内部定义的columns和defaultColDef数组/对象,会在每次组件状态更新(比如setDrawerOpen触发重渲染)时被重新创建。Ag Grid检测到列定义引用变化,会重新初始化列配置,导致过滤器状态丢失。

解决方案

使用React的useMemo缓存columns和defaultColDef,确保只有当依赖项变化时才重新生成,保持引用稳定。

修改后的代码

import React, { useState, useMemo } from "react";
import { AgGridReact } from "ag-grid-react";
import "ag-grid-enterprise";

import data from "./data.js";
import filters from "./filters.js";
import "./table.scss";

const Table = () => {
  const [drawerOpen, setDrawerOpen] = useState(false);

  // 用useMemo缓存columns,依赖项为filters.types
  const columns = useMemo(() => [
    {
      headerClass:
        "base__name-header-cell table__name-header-cell",
      headerName: "Name",
      field: "name",
      cellClass: () => "base__name-cell table__name-cell",
      pinned: "left",
      sort: "asc",
      suppressFloatingFilterButton: true,
      floatingFilterComponentParams: {
        className: "table__name-search-filter",
        option: "contains",
      },
      filter: "agTextColumnFilter",
      minWidth: 270,
      exportable: true,
    },
    {
      headerName: "Type",
      cellClass: "type-cell",
      field: "type",
      filter: "agSetColumnFilter",
      filterParams: {
        values: filters.types,
        suppressAndOrCondition: true,
        defaultToNothingSelected: true,
        apply: true,
        newRowsAction: "keep",
      },
      suppressFloatingFilterButton: true,
      filterValueGetter: (params) => {
        let types = [...params.data.types];
        return types;
      },
      minWidth: 160,
      maxWidth: 200,
      exportable: true,
    },
  ], [filters.types]);

  // 用useMemo缓存defaultColDef,无依赖项
  const defaultColDef = useMemo(() => ({
    suppressHeaderMenuButton: true,
    sortable: true,
    filter: true,
    floatingFilter: true,
    sortingOrder: ["desc", "asc", null],
    headerCheckboxSelectionFilteredOnly: true,
    filterParams: { newRowsAction: "keep" },
  }), []);

  const openDrawer = () => {
    setDrawerOpen(true);
  };

  const onCellClicked = () => {
    openDrawer();
  };

  return (
    <div className="ag-theme-alpine-dark base table js-table">
      <div>
        <AgGridReact
          deltaRowDataMode={true}
          columnDefs={columns}
          defaultColDef={defaultColDef}
          domLayout="autoHeight"
          onCellClicked={onCellClicked}
          paginationPageSize={50}
          rowData={data}
          rowHeight={40}
          rowSelection="multiple"
          suppressRowClickSelection
          autoSizeStrategy={{ type: "fitCellContents" }}
          getRowId={(params) => params.data.assessmentId}
        />
      </div>
    </div>
  );
};

export default Table;

关键说明

  • useMemo确保columns和defaultColDef在组件重渲染时保持相同引用,Ag Grid不会重新初始化列配置
  • 依赖项数组根据实际情况设置:如果filters.types是动态数据,需要加入依赖;如果是静态数据,加入依赖也不会影响,能保证引用稳定
  • 该方案同样适用于其他因组件重渲染导致Ag Grid状态丢失的场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 03:16:09