Q:

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

A:

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
};

A:

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>
  </>
)}

