This post provides code samples and shows how to utilize useState or useRef hooks and gridReady event to maintain access to Grid API and Column API. You will also be able to see a demo of useRef vs, useState and discusses the difference between the two versions.
Check here for code samples.
AG-GRID IN REACT 16.8.0+
ag-Grid has an impressive set of features, matched by unusually comprehensive documentation. The issue is that at this moment (February 2020), most of the React-specific examples are written for class components. Because of this, using the grid inside a function (functional) component could be slightly challenging. One of the things that are not so obvious is how to access Grid API and Column API...
Grid and Column APIs have over 150 methods that let you manipulate everything from cell focus to column width. The docs suggest obtaining and saving references to these APIs inside gridReady event handler:
class GridExample extends Component {
onGridReady = params => {
this.gridApi = params.api;
this.gridColumnApi = params.columnApi;
}
render() {
return (
<AgGridReact
onGridReady={this.onGridReady}
/>
);
}
}
Such approach works nicely in a class component but doesn't work when component is "just" a function. Worry not! useState and useRef hooks (part of React 16.8.0) can help you access the APIs in a function component and it's all quite easy!
I've asked ag-Grid team if they have a preference between useState
and useRef
and they don't, so I will show you the two options and you can pick the one that suits you.
Here's a component that uses selectAll
method from Grid API and moveColumnByIndex
method from Column API with the help of useState
hook:
import React, { useState } from "react";
import { AgGridReact } from "ag-grid-react";
import { columnDefs } from "./columnDefs";
import { rowData } from "./rowData";
import "ag-grid-community/dist/styles/ag-grid.css";
import "ag-grid-community/dist/styles/ag-theme-balham.css";
const AgGridWithUseState = () => {
console.log("AgGridWithUseState Render");
const [gridApi, setGridApi] = useState();
const [columnApi, setColumnApi] = useState();
return (
<div className="example">
<h1>API access with useState</h1>
<div>
<button
onClick={() => gridApi && gridApi.selectAll()}>
Grid API selectAll()
</button>
<button
onClick={() => columnApi && columnApi.moveColumnByIndex(0, 1)}>
Column API moveColumnByIndex(0, 1)
</button>
</div>
<div className="ag-theme-balham">
<AgGridReact
columnDefs={columnDefs}
rowData={rowData}
rowSelection="multiple"
onGridReady={params => {
console.log("AgGridWithUseState Grid Ready");
setGridApi(params.api);
setColumnApi(params.columnApi);
}}
/>
</div>
</div>
);
};
export default AgGridWithUseState;
and below is the exact same thing done with useRef
:
import React, { useRef } from "react";
import { AgGridReact } from "ag-grid-react";
import { columnDefs } from "./columnDefs";
import { rowData } from "./rowData";
import "ag-grid-community/dist/styles/ag-grid.css";
import "ag-grid-community/dist/styles/ag-theme-balham.css";
const AgGridWithUseRef = () => {
console.log("AgGridWithUseRef Render");
const gridApi = useRef();
const columnApi = useRef();
return (
<div className="example">
<h1>API access with useRef</h1>
<div>
<button
onClick={() => gridApi.current && gridApi.current.selectAll()}>
Grid API selectAll()
</button>
<button
onClick={() => columnApi.current && columnApi.current.moveColumnByIndex(0, 1)}>
Column API moveColumnByIndex(0, 1)
</button>
</div>
<div className="ag-theme-balham">
<AgGridReact
columnDefs={columnDefs}
rowData={rowData}
rowSelection="multiple"
onGridReady={params => {
console.log("AgGridWithUseRef Grid Ready");
gridApi.current = params.api;
columnApi.current = params.columnApi;
}}
/>
</div>
</div>
);
};
export default AgGridWithUseRef;
Check the function assigned to onGridReady
property to find out how to retrieve and keep references to the APIs. Button's onClick
handlers show you how to use the APIs.
USEREF VS USESTATE (DEMO)
The app uses React 16.12.0 and ag-Grid Community 22.1.1 (I've tested it in Chrome 80, Firefox 73, Edge 44).
Clone the repo, do npm install
and npm start
to run the app locally (just like with any other thing started with create-react-app
)...
The demo shows access to selectAll
method from Grid API and moveColumnByIndex
method from Column
API. This application has two grids that differ only in the way the APIs are accessed (one uses useState
hook, the other goes with useRef
hook).
What's the Difference between useState and useRef Version?
It boils down to the way hooks are designed to work. useState causes component rerender and useRef doesn't. You can see the difference if you open the console and check the log:
Notice two "AgGridWithUseState Render
" lines after "AgGridWithUseState Grid Ready
".
This happens because Grid
and Column
APIs are set by two calls to state hook setters and that causes component rerenders. Sounds bad? Remember that in React, a component rerender doesn't necessary mean any DOM change has to be applied. ag-Grid is also smart enough to avoid unnecessary work. useState
triggers rendering by design and it lets you write the component in a more declarative way. For example, you could keep rowData
and columnDefs
in state and have the grid update itself without explicit API calls...
How about the useRef
approach? Use it if you don't need to run any action as a result of API reference being set.