Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access ag-Grid API in React function component (useState hook)?

What is the best way of accessing ag-Grid API inside of React function component?

I have to use some of the methods from API (getSelectedNodes, setColumnDefs etc.) so I save a reference to the API (using useState hook) in onGridReady event handler:

onGridReady={params => {
    setGridApi(params.api);
}}

and then I can call the API like this: gridApi.getSelectedNodes()

I haven't noticed any problems with this approach, but I'm wondering if there's more idiomatic way?

Stack:

  • ag-grid-community & ag-grid-react 22.1.1
  • react 16.12.0
like image 323
user1068352 Avatar asked Feb 07 '20 15:02

user1068352


People also ask

What is hook How useState () and Hooks effect are use?

Hooks State In the above example, useState is the Hook which needs to call inside a function component to add some local state to it. The useState returns a pair where the first element is the current state value/initial value, and the second one is a function which allows us to update it.

What is the output of useState () hook?

The useState hook is a special function that takes the initial state as an argument and returns an array of two entries.

What is the use of useState hook in React?

The useState Hook can be used to keep track of strings, numbers, booleans, arrays, objects, and any combination of these! We could create multiple state Hooks to track individual values.

What is useState () React?

A Hook is a special function that lets you “hook into” React features. For example, useState is a Hook that lets you add React state to function components.


3 Answers

We find the most idiomatic way to use a ref. As the api is not a state of our component. It is actually possible to simply do:

<AgGridReact ref={grid}/>

and then use it with

grid.current.api

Here an example:

import React, { useRef } from 'react'
import { AgGridReact } from 'ag-grid-react'
import { AgGridReact as AgGridReactType } from 'ag-grid-react/lib/agGridReact'

const ShopList = () => {
  const grid = useRef<AgGridReactType>(null)

 ...

  return (
    <AgGridReact ref={grid} columnDefs={columnDefs} rowData={shops} />
  )

}

The good thing here is, that you will have access to the gridApi but als to to the columnApi. Simply like this:

// rendering menu to show/hide columns:
{columnDefs.map(columnDef =>
  <>
    <input
    type='checkbox'
    checked={
        grid.current
        ? grid.current.columnApi.getColumn(columnDef.field).isVisible()
        : !(columnDef as { hide: boolean }).hide
    }
    onChange={() => {
        if (grid.current?.api) {
        const col = grid.current.columnApi.getColumn(columnDef.field)
        grid.current.columnApi.setColumnVisible(columnDef.field, !col.isVisible())
        grid.current.api.sizeColumnsToFit()
        setForceUpdate(x => ++x)
        }
    }}
    />
    <span>{columnDef.headerName}</span>
  </>
)}
like image 77
pa1nd Avatar answered Sep 21 '22 03:09

pa1nd


Well I am doing it in my project. You can use useRef hook to store gridApi.

const gridApi = useRef();

const onGridReady = params => {

   gridApi.current = params.api;  // <== this is how you save it

   const datasource = getServerDataSource(
     gridApi.current,
     {
       size: AppConstants.PAGE_SIZE,
       url: baseUrl,
       defaultFilter: props.defaultFilter
     }
   );

  gridApi.current.setServerSideDatasource(datasource); // <== this is how you use it
};
like image 24
Sushmit Sagar Avatar answered Sep 25 '22 03:09

Sushmit Sagar


I'm running into the same issue but here is a workaround that at least can get you the selected rows. Essentially what I'm doing is sending the api from the agGrid callbacks to another function. Specifically I use OnSelectionChanged callback to grab the current row node. Example below:

  const onSelectionChanged = params => {
    setDetails(params.api.getSelectedRows());
  };

return (<AgGridReact
          columnDefs={agData.columnDefs}
          rowSelection={'single'}
          enableCellTextSelection={true}
          defaultColDef={{
            resizable: true,
          }}
          rowHeight={50}
          rowData={agData.rowData}
          onCellFocused={function(params) {
            if (params.rowIndex != null) {
              let nNode = params.api.getDisplayedRowAtIndex(params.rowIndex);
              nNode.setSelected(true, true);
            }
          }}
          onSelectionChanged={function(params) {
            onSelectionChanged(params);
            params.api.sizeColumnsToFit();
          }}
          onGridReady={function(params) {
            let gridApi = params.api;
            gridApi.sizeColumnsToFit();
          }}
          deltaRowDataMode={true}
          getRowNodeId={function(data) {
            return data.id;
          }}
        />);
like image 43
Jose R. Perez Avatar answered Sep 23 '22 03:09

Jose R. Perez