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

AgGrid React中如何防止自定义ToolPanel重渲染时自动折叠

问题根因

自动折叠的核心原因是写法导致每次重渲染都会给AgGrid传入全新的工具面板配置,AgGrid检测到组件引用变化后会直接销毁旧面板、重建新面板,展开状态自然会丢失,具体问题点有两个:

  • 你在sideBar配置里写的toolPanel: MyToolPanel({selected: selected})是直接执行组件函数拿返回值,不是传组件引用。每次父组件因为selected状态更新重渲染时,这里都会生成一个全新的函数,AgGrid会判定为换了个新工具面板,直接重置状态。
  • 自定义ToolPanel组件没有实现AgGrid要求的refresh方法,参数变化时AgGrid默认会重挂载组件,进一步导致状态丢失。
修复方案

第一步:修正自定义ToolPanel组件写法

不要写两层嵌套的返回函数,直接接收AgGrid传入的参数,同时加refresh静态方法告诉AgGrid组件可自主处理更新,不需要重挂载:

import { IToolPanelParams } from 'ag-grid-community';

const Container = styled.div`
  margin: 0px auto;
  padding: 10px;
`;

// 扩展AgGrid原生工具面板参数类型,加入自定义传参
export interface MyToolPanelParams extends IToolPanelParams {
  selected: MyRowData[];
}

export const MyToolPanel = (params: MyToolPanelParams) => {
  // 直接从AgGrid传入的params中取动态参数
  return (
    <Container>
      <AnotherComponentThatProcessesSelectedItems
        selected={params.selected}
      />
    </Container>
  );
};

// 关键:告诉AgGrid组件自己处理刷新逻辑,不需要销毁重建
MyToolPanel.prototype.refresh = () => true;

第二步:固定Grid配置引用,用官方规范传动态参数

所有传给AgGrid的配置项要用useMemo、useCallback包裹保证引用稳定,动态参数通过toolPanelParams字段传递,不要直接修改toolPanel的组件引用:

import { useCallback, useMemo, useState } from 'react';
import { AgGridReact } from 'ag-grid-react';
import { GridOptions } from 'ag-grid-community';

const [selected, setSelected] = useState<MyRowData[]>([]);

// 固定选中事件回调引用
const handleSelectionChanged = useCallback((e) => {
  setSelected(e.api.getSelectedRows());
}, []);

// 固定gridOptions引用,仅在依赖变化时更新
const gridOptions = useMemo<GridOptions>(() => ({
  onSelectionChanged: handleSelectionChanged,
  // 其余原有gridOptions配置统一放在这里
}), [handleSelectionChanged]);

// 固定侧边栏配置引用,toolPanel直接传组件本身,不要加括号执行
const sideBarConfig = useMemo(() => ({
  toolPanels: [
    "columns",
    "filters",
    {
      id: 'myToolPanel',
      labelDefault: 'My Tool Panel',
      labelKey: 'myToolPanel',
      iconKey: 'columns',
      toolPanel: MyToolPanel, // 直接传组件引用,不要提前执行
      toolPanelParams: {
        selected: selected // 动态变化的参数走这个字段传递
      }
    }
  ]
// 仅在selected变化时更新参数,组件引用始终保持不变
}), [selected]);

return (
  <AgGridReact
    gridOptions={gridOptions}
    sideBar={sideBarConfig}
  />
);

额外兜底方案(极端场景使用)

如果遇到特殊AgGrid版本仍存在状态重置问题,可以主动记忆面板展开状态,Grid就绪后主动恢复:

// 新增状态记录当前展开的面板ID
const [openedToolPanel, setOpenedToolPanel] = useState<string | null>(null);

const gridOptions = useMemo<GridOptions>(() => ({
  onSelectionChanged: handleSelectionChanged,
  // 监听面板开关状态,实时记录
  onToolPanelVisibleChanged: (e) => {
    if (e.visible) {
      setOpenedToolPanel(e.key);
    } else if (openedToolPanel === e.key) {
      setOpenedToolPanel(null);
    }
  },
  // Grid加载完成后主动恢复展开状态
  onGridReady: (e) => {
    if (openedToolPanel) {
      e.api.openToolPanel(openedToolPanel);
    }
    // 其余原有onGridReady逻辑放在这里
  }
}), [handleSelectionChanged, openedToolPanel]);

内容的提问来源于stack exchange,提问作者Ryan Pierce Williams

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 14:18:18