AG Grid in React: A Practical Data Grid Tutorial (with Example)
If you’ve ever tried to build an interactive table in React and ended up re-inventing sorting,
filtering, pagination, and inline editing… welcome to the club. The point of using a mature
React data grid
is to stop fighting table plumbing and start shipping features.
This guide is a hands-on AG Grid tutorial:
you’ll install the library, render your first grid, and enable the “must-have” bits—AG Grid filtering sorting,
AG Grid pagination, and AG Grid cell editing—with one cohesive example.
What is AG Grid (in one sentence)?
AG Grid is a high-performance React grid component that renders large datasets efficiently and adds
production-ready features like sorting, filtering, editing, grouping, and exports—without you building a spreadsheet engine from scratch.
AG Grid installation in React (and the #1 reason your grid “shows nothing”)
The fastest AG Grid installation
path is via npm/yarn. AG Grid ships as packages you add to your React project, then you import a theme CSS and give the grid a height.
That last part is where many “AG Grid not rendering” bugs live: no height means no visible rows.
The React wrapper package is ag-grid-react; the core is ag-grid-community.
(Enterprise features are in a separate package/license, but you can build a lot on Community.)
For a typical app, you’ll also import an Alpine theme and the base grid CSS.
If you’re optimizing for voice search: To install AG Grid in React, install ag-grid-react and ag-grid-community,
import the grid CSS + a theme CSS, and set a fixed height on the grid container. That’s the full spell.
npm i ag-grid-react ag-grid-community- Import CSS:
ag-grid-community/styles/ag-grid.cssand a theme likeag-grid-community/styles/ag-theme-alpine.css - Wrap the grid in a div with a height (e.g.,
height: 600px)
A minimal AG Grid React example you can paste into your app
This AG Grid React example uses realistic defaults: sortable/filterable columns, pagination,
and editable cells. It also demonstrates two “grown-up” practices that matter when your grid is not a toy:
memoizing column definitions and providing stable row IDs.
Why care about stable row IDs? Because grids are stateful beasts. Sorting, selection, editing, and updates
behave much better when AG Grid can reliably track which row is which. In AG Grid terms, that’s getRowId.
This is the point where some people decide they just need a simple React table component.
If that’s you, great. If you need spreadsheet-like UX, large datasets, and fewer DIY regrets, keep going.
import React, { useMemo, useState } from "react";
import { AgGridReact } from "ag-grid-react";
import "ag-grid-community/styles/ag-grid.css";
import "ag-grid-community/styles/ag-theme-alpine.css";
type Row = {
id: string;
make: string;
model: string;
price: number;
inStock: boolean;
};
export default function CarsGrid() {
const [rowData, setRowData] = useState<Row[]>([
{ id: "1", make: "Tesla", model: "Model 3", price: 42990, inStock: true },
{ id: "2", make: "Ford", model: "Mustang", price: 55990, inStock: false },
{ id: "3", make: "Toyota", model: "Corolla", price: 23990, inStock: true },
{ id: "4", make: "Volvo", model: "XC40", price: 39990, inStock: true },
]);
const columnDefs = useMemo(
() => [
{ field: "make", sortable: true, filter: true, editable: true },
{ field: "model", sortable: true, filter: true, editable: true },
{
field: "price",
sortable: true,
filter: "agNumberColumnFilter",
editable: true,
valueParser: (p: any) => Number(p.newValue || 0),
},
{
field: "inStock",
headerName: "In stock",
sortable: true,
filter: true,
editable: true,
},
],
[]
);
const defaultColDef = useMemo(
() => ({
flex: 1,
minWidth: 140,
resizable: true,
floatingFilter: true,
}),
[]
);
return (
<div style={{ height: 560, width: "100%" }} className="ag-theme-alpine">
<AgGridReact<Row>
rowData={rowData}
columnDefs={columnDefs}
defaultColDef={defaultColDef}
getRowId={(p) => p.data.id}
pagination={true}
paginationPageSize={10}
animateRows={true}
onCellValueChanged={(e) => {
// Keep React state in sync if you need it (e.g., to save changes).
// For demo: write back the updated row.
setRowData((prev) => prev.map((r) => (r.id === e.data.id ? e.data : r)));
}}
/>
</div>
);
}
Sorting and filtering: the “interactive table React” baseline
For most apps, the baseline for a usable React data table is: sort columns, filter values, and
make it obvious what’s happening. In AG Grid, sorting is as simple as sortable: true, and filtering is
filter: true. That’s not magic; it’s just a library that’s already fought these battles.
The first decision is whether you want global filtering, per-column filtering, or both.
AG Grid supports quick filtering (search-like) and column filters (type-aware, like number/date/text).
In the example above, we enabled floatingFilter: true so each column gets an inline filter UI.
A practical tip: if you plan to use server-side filtering/sorting later, start by keeping your column
filter types explicit (e.g., agNumberColumnFilter for numeric columns). It makes behavior predictable,
and it makes backend query mapping less… interpretive.
Pagination: client-side vs server-side (and when your dataset stops being cute)
AG Grid pagination can be client-side (you already have all rows in memory) or server-side
(you fetch pages/blocks as needed). For small-to-medium datasets, client-side pagination is a quick win:
enable pagination and set paginationPageSize. Done.
But if you’re building a real admin panel, you’ll eventually hit the moment where loading 200,000 rows
into a browser tab feels less like engineering and more like performance art. That’s when you consider
server-side row models (infinite scrolling, server-side pagination, etc.) and let the grid request data
in chunks.
The key architectural point is this: pagination is a UI feature, but the data strategy is a product decision.
If users must search across all records, server-side filtering/sorting becomes part of “correctness,” not just speed.
Plan for that early, especially if you’re selecting a React data grid library for long-term use.
Cell editing: making a React spreadsheet table without building Excel
AG Grid cell editing starts with editable: true, but the real work is validating, parsing,
and persisting changes. In the example, the price column uses valueParser to coerce input into a number.
That small detail prevents “42,990” from becoming “42990??? maybe” depending on user input quirks.
Editing also raises the “source of truth” question: should the grid own state, or should React own state?
If you’re just editing locally, the grid can manage it. If edits must be saved, audited, or reflected elsewhere,
sync changes through callbacks like onCellValueChanged and update your React state (or your store).
If you’re aiming for a React spreadsheet table feel, you’ll likely add keyboard navigation, fill handle,
custom editors, and validation messages. That’s where mature grid ecosystems shine: you can evolve from “editable cell”
to “business-grade inline editor” without rewriting your table every sprint.
Choosing AG Grid vs a simpler React table component (a pragmatic checklist)
Not every project needs AG Grid. Sometimes you just need to render a table with a couple of columns
and call it a day. But if your stakeholders are already saying things like “can we add inline edits, exports,
complex filters, and it should still be fast?”, you’re in data-grid territory whether you like it or not.
AG Grid tends to be a strong fit when performance and feature depth matter: virtualization, rich filtering,
complex column behaviors, row grouping/pivoting (often enterprise), and the general expectation that the grid
behaves like a professional tool. It’s the difference between “table” and “application inside a table.”
Here’s a reality-based way to decide. If you check multiple boxes, a full React grid component is justified,
and the time you save will be measured in weeks, not minutes.
- You need sorting/filtering/editing/pagination together (not as separate plugins you’ll glue forever).
- You expect large datasets and want smooth scrolling (virtualization).
- You need consistent UX: resizing, pinned columns, keyboard support, export workflows.
- You want a grid that scales from MVP to “this is now the product.”
Common gotchas (so you don’t spend an afternoon debugging a blank rectangle)
The most common “why is my AG Grid React blank?” issue is missing height or missing theme class.
You need both: a container with a height and a theme class like ag-theme-alpine. Without a height,
the grid is technically rendered—but it has zero pixels to work with. Very minimalist. Too minimalist.
Another frequent issue is redefining columnDefs on every render. If you create new arrays/objects each time,
the grid may treat it as a full reconfiguration. Memoize with useMemo (as shown) and keep props stable.
This matters a lot once you add selection, editing, or frequent updates.
Finally, if you load data asynchronously, make sure your rowData is an array (even an empty one) and your
field names match. When wiring APIs, it’s easy to map price_cents but define a column for price,
then blame the grid for being “empty.” The grid is innocent; it’s just literal.
FAQ
Is AG Grid free to use in React?
Yes—AG Grid Community is free and covers core features like sorting, filtering, pagination, and basic editing.
Some advanced capabilities are part of AG Grid Enterprise and require a paid license.
How do I enable sorting and filtering in AG Grid React?
Set sortable: true and filter: true on your column definitions (or via defaultColDef),
then optionally add floatingFilter: true for inline filter inputs.
How do I implement pagination, and when should it be server-side?
For client-side pagination, set pagination={true} and paginationPageSize. Use server-side approaches
when datasets are large or when filtering/sorting must work across records that aren’t loaded in the browser.
Semantic core (keyword clusters)
Main: AG Grid React; React data grid; AG Grid tutorial; React table component; React data table; React grid component; React data grid library; AG Grid React example
Supporting: AG Grid installation; AG Grid filtering sorting; AG Grid pagination; AG Grid cell editing; interactive table React; React spreadsheet table; editable data grid React; React table with sorting and filtering
Long-tail/LSI: how to install ag grid in react; ag grid theme alpine; columnDefs and rowData; getRowId; quick filter; server-side pagination React grid; virtualization; inline editing

