AG Grid React: The Only Guide You’ll Actually Finish Reading







AG Grid React: Complete Setup, Filtering & Cell Editing Guide






AG Grid React: The Only Guide You’ll Actually Finish Reading

Updated 2025  ·  14 min read  ·  Covers AG Grid Community v31+, React 18+

Why AG Grid Is the Benchmark for React Data Grids

If you’ve ever tried to build a serious React data grid
from scratch — with sorting, filtering, pagination, and inline editing all working in concert — you already know the feeling.
It starts innocently with a plain HTML <table>, then you add a library, then another,
then you’re maintaining three half-working packages and questioning your career choices.
AG Grid exists to end that cycle.

AG Grid is a React data grid library (also available for Angular, Vue, and vanilla JS)
that handles datasets from a few dozen rows to hundreds of thousands — without breaking a sweat.
Its Community edition is free and open-source under the MIT license, covering everything most applications genuinely need:
column sorting and filtering, pagination, cell editing, custom renderers, and virtual scrolling.
The Enterprise tier layers on row grouping, pivoting, Excel export, and server-side row models
for teams building internal dashboards or data-heavy SaaS products.

What sets AG Grid apart from alternatives like React Table (TanStack Table) or Material UI’s DataGrid
is that it renders through its own high-performance engine rather than delegating to the browser’s
default DOM layout. That’s why it can comfortably display 100,000 rows with virtual scrolling
while a naive <table> implementation would melt your laptop fan.
The architecture behind AG Grid’s React integration
is deliberately close to the framework’s mental model — you describe columns and data declaratively,
and the grid handles the rest.

AG Grid Installation and Project Setup

Getting AG Grid installed
in a React project takes about ninety seconds — and that includes the time it takes to decide
whether you want the Community or Enterprise package. For most projects, start with Community.
You can always upgrade later without rewriting your column definitions.

Open a terminal inside your React project (Create React App, Vite, or Next.js all work fine)
and run:

npm install ag-grid-community ag-grid-react
# or with yarn
yarn add ag-grid-community ag-grid-react

Two packages, no exotic peer dependencies. ag-grid-community is the core engine;
ag-grid-react is the thin React wrapper that exposes the <AgGridReact> component.
Once installed, import the CSS theme of your choice. AG Grid ships with several built-in themes —
Alpine is the modern default, Balham leans more corporate,
and Material follows Google’s design language.
All themes can be customized via CSS variables without touching the library source.

// Import once in your entry file or the component file itself
import 'ag-grid-community/styles/ag-grid.css';
import 'ag-grid-community/styles/ag-theme-alpine.css';

One thing worth noting before you move on: AG Grid v28+ introduced a new modular CSS import system.
If you’re on an older tutorial and the styles look broken, this is almost certainly why.
Always match your import paths to the package version you actually installed.
The package.json knows the truth; the Stack Overflow answer from 2021 does not.

Building Your First AG Grid React Example

With installation behind us, let’s wire up a working AG Grid React example
one with real column definitions, real data, and just enough interactivity to be useful.
The two props you cannot avoid are rowData and columnDefs.
Everything else is optional (though you’ll quickly want most of it).

import React, { 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';

const App = () => {
  const [rowData] = useState([
    { make: 'Tesla',  model: 'Model Y',  price: 64990, year: 2024 },
    { make: 'Toyota', model: 'Camry',    price: 27990, year: 2024 },
    { make: 'Ford',   model: 'Mustang',  price: 32995, year: 2024 },
    { make: 'BMW',    model: 'M3',       price: 74900, year: 2024 },
  ]);

  const [columnDefs] = useState([
    { field: 'make',  headerName: 'Make'  },
    { field: 'model', headerName: 'Model' },
    { field: 'price', headerName: 'Price', valueFormatter: p => `$${p.value.toLocaleString()}` },
    { field: 'year',  headerName: 'Year'  },
  ]);

  const defaultColDef = {
    sortable:  true,
    filter:    true,
    resizable: true,
    flex:      1,
  };

  return (
    <div className="ag-theme-alpine" style={{ height: 400 }}>
      <AgGridReact
        rowData={rowData}
        columnDefs={columnDefs}
        defaultColDef={defaultColDef}
      />
    </div>
  );
};

export default App;

Notice the defaultColDef object — this is one of AG Grid’s most useful patterns.
Instead of repeating sortable: true, filter: true on every column,
you define shared defaults once and override them per column only when needed.
In this example, every column is sortable, filterable, and resizable by default,
and the grid distributes available width evenly with flex: 1.

The wrapping <div> carries the theme class (ag-theme-alpine)
and must have an explicit height. AG Grid fills 100% of its container’s height —
it doesn’t auto-size to content by default. For a full-page layout you’d set the container
to height: 100vh; for an embedded panel you provide a fixed pixel value or
use domLayout="autoHeight" on the grid component itself.
This trips up almost every developer the first time.

AG Grid Filtering and Sorting in Depth

AG Grid filtering
works on two levels: column-level filters (the little funnel icon in each header)
and the Quick Filter, which is a global search box you wire up yourself.
Column filters include text, number, date, and set filters out of the box.
The set filter — think Excel’s dropdown checklist — is a Community feature and
particularly useful for categorical columns like status, region, or product type.

// Column-specific filter configuration
const columnDefs = [
  {
    field: 'price',
    filter: 'agNumberColumnFilter',  // number filter with range operators
    filterParams: {
      filterOptions: ['equals', 'lessThan', 'greaterThan', 'inRange'],
      defaultOption: 'greaterThan',
    },
  },
  {
    field: 'make',
    filter: 'agSetColumnFilter',     // checklist-style filter
  },
];

// Quick Filter — wire it to a search input
<input
  type="text"
  placeholder="Search..."
  onChange={e => gridRef.current.api.setQuickFilter(e.target.value)}
/>

Sorting
in AG Grid is equally flexible. By default, clicking a column header cycles through
ascending → descending → no sort. You can disable sorting for specific columns
with sortable: false, or implement multi-column sorting by holding
Shift while clicking additional headers.
If you need to sort programmatically — say, after loading new data —
use the Grid API: gridRef.current.api.applyColumnState({ state: [{ colId: 'price', sort: 'desc' }] }).

For larger datasets, consider server-side filtering and sorting.
Rather than loading everything into the browser and letting the grid filter locally,
you respond to grid events by sending updated query parameters to your API.
AG Grid fires onFilterChanged and onSortChanged events
that give you the current filter model and sort state — format those into your API call
and swap rowData with the fresh response. This pattern keeps the browser
fast and your backend in control of the data contract.

Pagination in AG Grid React

Enabling AG Grid pagination
is genuinely one of the library’s “why isn’t everything this easy” moments.
Two props on <AgGridReact> are all you need for client-side pagination:
pagination={true} and paginationPageSize={20}.
The grid handles the page controls, row slicing, and page-size selector automatically.

<AgGridReact
  rowData={rowData}
  columnDefs={columnDefs}
  defaultColDef={defaultColDef}
  pagination={true}
  paginationPageSize={25}
  paginationPageSizeSelector={[10, 25, 50, 100]}
/>

The paginationPageSizeSelector prop (introduced in v30) renders a dropdown
that lets users choose their preferred page size — a small UX detail that noticeably
reduces “where is the rest of my data?” support tickets. If you want to control the page
programmatically — for example, navigating to a specific page on mount —
use gridRef.current.api.paginationGoToPage(n) where n is zero-indexed.

When working with server-side data, pagination integrates with AG Grid’s
Infinite Row Model or Server-Side Row Model.
With the Infinite Row Model, the grid fetches pages lazily as the user scrolls or navigates.
You implement a datasource object with a getRows method
that receives start/end row indices and a success callback.
This is the go-to pattern for REST APIs that support limit/offset pagination
and don’t want to dump 50,000 records into a React component’s state.

AG Grid Cell Editing: Making Your React Table Interactive

A React data grid that can’t be edited is just an expensive table.
AG Grid’s cell editing
system is one of its strongest differentiators — it supports inline editing with multiple
built-in editors, custom React editor components, and full keyboard navigation
that matches what users expect from spreadsheet applications.

The simplest path to editable cells: set editable: true on a column definition
or in defaultColDef to make all columns editable. Double-clicking a cell
(or pressing F2) activates the editor. AG Grid detects the column’s data type
and uses an appropriate default editor — text input for strings, numeric input for numbers.
When editing finishes, the onCellValueChanged event fires with the old and new values,
which is where you’d call your API to persist the change.

const columnDefs = [
  { field: 'make',  editable: false },   // read-only
  { field: 'model', editable: true  },   // text editor
  {
    field: 'price',
    editable: true,
    cellEditor: 'agNumberCellEditor',    // numeric editor
    cellEditorParams: { min: 0, max: 500000 },
  },
  {
    field: 'status',
    editable: true,
    cellEditor: 'agSelectCellEditor',    // dropdown editor
    cellEditorParams: { values: ['Available', 'Sold', 'Reserved'] },
  },
];

// Capture changes and send to API
const onCellValueChanged = (params) => {
  console.log('Changed:', params.colDef.field, params.oldValue, '→', params.newValue);
  // saveToDatabase(params.data);
};

For more complex editing scenarios — rich text, date pickers, autocomplete fields —
you can build a custom cell editor as a regular React component.
Wrap it with forwardRef, implement the getValue() method via
useImperativeHandle, and register it in the grid’s components prop.
AG Grid will call getValue() when the user commits the edit,
giving you complete control over how values are captured and validated
without fighting the grid’s internal state.

Advanced Patterns: Virtual Scrolling, Column Groups, and the Grid API

Once your basic React grid component
is running, the real productivity gains come from features you didn’t know you needed
until a stakeholder asks why the table freezes with 10,000 rows.
Virtual scrolling is enabled by default in AG Grid — only the rows visible
in the viewport are rendered in the DOM, regardless of total dataset size.
You don’t have to configure anything; just make sure you’re not using domLayout="autoHeight"
on large datasets, because that mode renders all rows to calculate height, defeating the purpose.

Column groups let you create multi-level headers — useful for financial tables,
analytics dashboards, or any layout where columns naturally belong to categories.
You define them by nesting columnDefs inside a parent object with a headerName:

const columnDefs = [
  {
    headerName: 'Vehicle Info',
    children: [
      { field: 'make',  headerName: 'Make'  },
      { field: 'model', headerName: 'Model' },
    ],
  },
  {
    headerName: 'Pricing',
    children: [
      { field: 'price', headerName: 'MSRP'   },
      { field: 'tax',   headerName: 'Tax'    },
    ],
  },
];

The Grid API is AG Grid’s escape hatch for everything that isn’t covered
by declarative props. Access it via gridRef.current.api after the grid mounts.
Common uses include: exportDataAsCsv() to trigger a CSV download,
sizeColumnsToFit() to redistribute column widths after a container resize,
getSelectedRows() to retrieve rows the user has checked,
and applyTransaction() to add, update, or remove specific rows without
re-rendering the entire dataset — critical for real-time data feeds.

Choosing Between AG Grid and Other React Table Libraries

The React ecosystem has no shortage of table and grid solutions.
TanStack Table (formerly React Table) is a headless utility — it provides logic but zero UI,
which is perfect if you need pixel-perfect control and are willing to build every visual detail yourself.
Material UI’s DataGrid is beautifully integrated with MUI’s design system but hits a performance wall
on large datasets in the Community version.
AG Grid occupies the middle and upper tier: opinionated enough to be productive immediately,
flexible enough to accommodate complex enterprise requirements, and performant enough
that “it’s the grid’s fault” almost never enters the conversation.

The Community vs. Enterprise decision deserves a practical framing rather than a feature checklist.
Ask yourself two questions: does the application need row grouping or pivoting
(summarizing data the way Excel pivot tables do), and does it need to export to Excel format
(not just CSV)?
If yes to either, Enterprise is probably worth the license cost.
If your requirements are filtering, sorting, pagination, editing, and custom renderers,
Community covers all of it and costs nothing.

  • AG Grid Community — sorting, filtering, pagination, cell editing, custom renderers, CSV export, virtual scrolling, column groups
  • AG Grid Enterprise — everything above, plus row grouping, pivoting, tree data, Excel export, range selection, server-side row model, integrated charts

One honest caveat: AG Grid’s bundle size is not trivial.
ag-grid-community adds roughly 250–300 KB to a production build (gzipped: ~90 KB).
For a data-heavy internal tool or dashboard, this is irrelevant.
For a marketing landing page with one optional table, it’s worth reconsidering.
The right tool matches the problem — AG Grid is built for data-intensive React applications,
and in that context it earns its weight.

Performance Tips for Large React Data Grids

Handling large datasets in a React spreadsheet table context requires
a few deliberate choices beyond just enabling virtual scrolling.
First, avoid storing derived data in rowData — compute it in
valueGetter functions instead. Value getters run only for visible cells,
while pre-computed values in state inflate your data footprint for all rows simultaneously.
This matters at 10,000+ rows.

Second, use getRowId to give AG Grid a stable identity for each row.
Without it, the grid uses array index as the row identifier, which causes unnecessary
re-renders when rows are added, removed, or reordered.
With a stable id field, applyTransaction can surgically update
a single row without touching the rest — the same principle as React’s key prop,
applied at the grid level.

<AgGridReact
  rowData={rowData}
  columnDefs={columnDefs}
  getRowId={(params) => params.data.id}
  // Enable row buffer for smoother fast-scrolling
  rowBuffer={20}
  // Throttle updates to avoid flooding the grid with rapid state changes
  asyncTransactionWaitMillis={50}
/>

Third, wrap stable column definitions and callback functions in useMemo
and useCallback respectively. AG Grid compares column definitions by reference —
if columnDefs is defined inline in the render function, it’s a new array
on every render, forcing the grid to re-evaluate all columns on every state change.
A single useMemo call is the cheapest performance fix you’ll ever write.

Frequently Asked Questions

How do I install AG Grid in a React project?

Run npm install ag-grid-community ag-grid-react in your project root.
Import the grid CSS and your chosen theme CSS at the top of your component or entry file,
then render <AgGridReact rowData={...} columnDefs={[...]} />
inside a container <div> with the theme class and an explicit height.
That’s genuinely all it takes for a working, sortable, filterable grid.

What is the difference between AG Grid Community and Enterprise?

AG Grid Community is free and MIT-licensed. It covers sorting, filtering, pagination,
cell editing, custom cell renderers, virtual scrolling, column groups, and CSV export —
which handles the majority of real-world data grid requirements.
AG Grid Enterprise adds row grouping, pivot tables, tree data, Excel export,
range selection, server-side row models, and integrated charting,
all under a commercial license priced per developer.

How do I enable cell editing in AG Grid React?

Add editable: true to any column definition, or set it in defaultColDef
to make all columns editable by default. AG Grid provides built-in editors for text, numbers,
dates, and select lists via cellEditor property values like
'agNumberCellEditor' or 'agSelectCellEditor'.
Listen to onCellValueChanged to capture edits and persist them to your backend.
For fully custom editing UI, build a React component with forwardRef
and register it in the grid’s components prop.

Title: AG Grid React: Complete Setup, Filtering & Cell Editing Guide
Description: Master AG Grid in React — from installation and column setup to filtering, sorting, pagination, and cell editing. Practical examples included.

Semantic core used: AG Grid React, React data grid, AG Grid tutorial, React table component, AG Grid installation,
React data table, AG Grid React example, interactive table React, AG Grid filtering sorting, React grid component,
AG Grid pagination, React spreadsheet table, AG Grid cell editing, React data grid library, AG Grid React setup,
enterprise data grid, columnDefs, rowData, defaultColDef, virtual scrolling grid, ag-grid-community, ag-grid-react,
ClientSideRowModel, onGridReady, editable grid React, grid API React, theme alpine AG Grid.



Leave a Reply

Your email address will not be published. Required fields are marked *