Search code examples
reactjsag-gridag-grid-react

AG-Grid React Column Group State Opening and Closing


I'm using AG Grid community edition, and I have a (likely) silly react problem. I have column groups where some columns are hidden until you click the column group header. I'm implementing a search function to query an API and display the data in the grid. I found that when you type anything into the search box, the column grouping will reset to its original state. For the life of me I cannot figure this out. I put everything into state, tried useMemo, useCallback and I still get this odd behavior.

Sample code below:

const App = () => {
  const [colDefs, setColDefs] = React.useState(columnDefs);
  const [searchString, setSearchString] = React.useState("");

  const onSearchInput = React.useCallback((e) => {
    setSearchString(e.target.value);
  }, []);

  return (
    <div>
      <input type="text" onChange={onSearchInput} />

      <div
        style={{ width: "100%", height: "80vh" }}
        className="ag-theme-material"
      >
        <AgGridReact
          columnDefs={colDefs}
          defaultColGroupDef={{ marryChildren: true }}
          defaultColDef={{
            filter: false,
            resizable: true,
            wrapHeaderText: true,
            autoHeaderHeight: true
          }}
          rowData={sample}
        />
      </div>
    </div>
  );
};

Edit reverent-wilbur-s9qrct

Steps to reproduce

  1. Expand column group "Project", see the newly exposed columns Business Unit and Budget Code (et.al.)
  2. Type something into the search box above the grid.
  3. Notice the column group is now collapsed.

Solution

  • I was able to fix this by moving the AG-Grid component to its own function component, and memoizing it with React.Memo.

    // ### GridComponent.js ###
    import { AgGridReact } from "ag-grid-react";
    
    export const GridComponent = React.memo((props) => {
      const { colDefs, rowData } = props;
      console.log(`Rendering ${rowData.length} rows`);
      return (
        <div
          style={{ width: "100%", height: "80vh" }}
          className="ag-theme-material"
        >
          <AgGridReact
            columnDefs={colDefs}
            defaultColGroupDef={{ marryChildren: true }}
            defaultColDef={{
              filter: false,
              resizable: true,
              wrapHeaderText: true,
              autoHeaderHeight: true
            }}
            rowData={rowData}
          />
        </div>
      );
    });
    

    And calling the component with props:

    // ## index.js ##
    <GridComponent colDefs={colDefs} rowData={rowData} />
    

    Complete example here, with some fake async data fetching operations.

    Edit nervous-lumiere-v6zd7t