Mastering Grid Options in AG-Grid React
Welcome back to our AG-Grid React series! In previous installments, we've explored setting up a basic grid, defining columns, and managing row data. Today, we're diving deep into a powerful concept that allows you to configure virtually every aspect of your grid's behavior and appearance: Grid Options.
Grid options provide a centralized way to define settings for your AG-Grid instance, ranging from row selection modes and pagination behavior to default column properties and event handling. Understanding and leveraging grid options is crucial for building robust and highly customizable data grids in your React applications.
What are Grid Options?
In AG-Grid, the term "Grid Options" refers to a plain JavaScript object that holds a collection of properties, callbacks, and event handlers. These settings dictate how the grid behaves and looks. While some core properties like rowData and columnDefs are often passed directly as props to the <AgGridReact> component for optimal Reactivity, many other configuration settings are typically bundled within the gridOptions object.
By using gridOptions, you can keep your component's JSX cleaner and manage complex configurations more effectively, especially when dealing with numerous settings that might not change frequently.
Defining and Applying Grid Options
To use grid options, you first define them as a JavaScript object. Then, you pass this object to the <AgGridReact> component via the gridOptions prop.
import React, { useState, useRef, useCallback, useMemo } from 'react';
import { AgGridReact } from 'ag-grid-react';
import 'ag-grid-community/styles/ag-grid.css';
import 'ag-grid-community/styles/ag-theme-quartz.css'; // Or any other theme
const MyGridComponent = () => {
const gridRef = useRef();
const [rowData, setRowData] = useState([
{ make: 'Tesla', model: 'Model Y', price: 64950, electric: true },
{ make: 'Ford', model: 'F-Series', price: 33850, electric: false },
{ make: 'Toyota', model: 'Corolla', price: 29600, electric: false },
]);
const [colDefs, setColDefs] = useState([
{ field: 'make' },
{ field: 'model' },
{ field: 'price' },
{ field: 'electric' },
]);
// Define your grid options here
const gridOptions = useMemo(() => ({
// Example grid options will go here
rowSelection: 'multiple',
pagination: true,
paginationPageSize: 10,
domLayout: 'autoHeight',
// ... more options
}), []); // Dependencies for useMemo if options rely on state/props
return (
<div className="ag-theme-quartz" style={{ height: 400, width: 600 }}>
<AgGridReact
ref={gridRef}
rowData={rowData}
columnDefs={colDefs}
gridOptions={gridOptions} // Pass the gridOptions object here
/>
</div>
);
};
export default MyGridComponent;
It's often a good practice to memoize your gridOptions object using useMemo if it's complex or contains function references. This prevents unnecessary re-renders of the grid component when the options object itself doesn't fundamentally change.
Key Grid Options and Their Usage
Let's explore some of the most commonly used and powerful grid options you can leverage to customize your AG-Grid React instance.
1. Default Column Definitions (`defaultColDef`)
This option allows you to set properties that apply to all columns in the grid unless overridden by individual column definitions. It's incredibly useful for applying common styling, resizing, filtering, or sorting behaviors globally.
const gridOptions = useMemo(() => ({
defaultColDef: {
filter: true, // Enable filtering for all columns
floatingFilter: true, // Show filter input below headers
sortable: true, // Enable sorting for all columns
resizable: true, // Allow resizing for all columns
flex: 1, // Make all columns flex-grow
minWidth: 100,
},
}), []);
2. Row Selection (`rowSelection`, `rowMultiSelectWithClick`)
Control how users can select rows. rowSelection can be 'single' or 'multiple'. rowMultiSelectWithClick allows multi-selection without requiring Ctrl/Shift keys.
const gridOptions = useMemo(() => ({
rowSelection: 'multiple', // Allows selecting multiple rows
rowMultiSelectWithClick: true, // Click to select multiple rows without modifier keys
suppressRowClickSelection: true, // Prevents row selection when clicking a row; useful if you have custom cell click handlers
}), []);
3. Pagination (`pagination`, `paginationPageSize`)
Enable and configure pagination to manage large datasets.
const gridOptions = useMemo(() => ({
pagination: true, // Enable pagination
paginationPageSize: 10, // Number of rows per page
paginationPageSizeSelector: [5, 10, 20, 50], // Allows users to change page size
}), []);
4. DOM Layout (`domLayout`)
Determines how the grid calculates its dimensions. Common values are 'normal' (default, grid takes available space), 'autoHeight' (grid adjusts height to fit all rows), and 'print' (optimizes for printing).
const gridOptions = useMemo(() => ({
domLayout: 'autoHeight', // Grid will resize its height to fit content
// Note: When using 'autoHeight', the parent container's height style should typically be removed or adjusted.
}), []);
5. Cell and Range Selection (`suppressCellSelection`, `enableRangeSelection`)
Beyond row selection, you can control cell selection and enable Excel-like range selection.
const gridOptions = useMemo(() => ({
suppressCellSelection: false, // Allow individual cell selection (default is true for AgGridReact props)
enableRangeSelection: true, // Enable Excel-like cell range selection
}), []);
6. Row Animations (`animateRows`)
Provides smooth animations when rows are added, removed, or reordered.
const gridOptions = useMemo(() => ({
animateRows: true, // Smooth animations for row operations
}), []);
7. Grid Callbacks and Events (`onGridReady`, `onCellClicked`, etc.)
While many event handlers can be passed directly as props to <AgGridReact>, they can also reside within gridOptions. onGridReady is particularly important as it provides access to the gridApi and columnApi once the grid is initialized.
const gridRef = useRef(); // Access grid API directly via ref
const onGridReady = useCallback((params) => {
// Access gridApi and columnApi here
console.log('Grid is ready:', params);
// You can also store it in a ref or state
// gridRef.current.api = params.api;
}, []);
const onCellClicked = useCallback((params) => {
console.log('Cell clicked:', params.value);
}, []);
const gridOptions = useMemo(() => ({
// If passed here, it overrides the prop version
// onGridReady: onGridReady,
// onCellClicked: onCellClicked,
// ... other options
}), [onGridReady, onCellClicked]); // Ensure these functions are memoized if passed in gridOptions
// ... in your JSX
return (
<AgGridReact
ref={gridRef}
rowData={rowData}
columnDefs={colDefs}
gridOptions={gridOptions}
onGridReady={onGridReady} // Preferred way to pass event handlers in React
onCellClicked={onCellClicked}
/>
);
Note on Events: For event handlers like onGridReady, onCellClicked, etc., it is generally recommended to pass them as direct props to <AgGridReact> rather than inside gridOptions. This allows React to manage them more efficiently and aligns better with React's component lifecycle and reconciliation process. However, AG-Grid does support them within gridOptions if you prefer that structure.
Putting It All Together: A Comprehensive Example
Let's see how a combination of these grid options can create a more feature-rich grid.
import React, { useState, useRef, useCallback, useMemo } from 'react';
import { AgGridReact } from 'ag-grid-react';
import 'ag-grid-community/styles/ag-grid.css';
import 'ag-grid-community/styles/ag-theme-quartz.css';
const AdvancedGridComponent = () => {
const gridRef = useRef();
const [rowData, setRowData] = useState([
{ make: 'Tesla', model: 'Model Y', price: 64950, electric: true, colour: 'Red' },
{ make: 'Ford', model: 'F-Series', price: 33850, electric: false, colour: 'Blue' },
{ make: 'Toyota', model: 'Corolla', price: 29600, electric: false, colour: 'White' },
{ make: 'Mercedes', model: 'EQS', price: 102310, electric: true, colour: 'Black' },
{ make: 'BMW', model: 'X5', price: 60700, electric: false, colour: 'Grey' },
{ make: 'Hyundai', model: 'Ioniq 5', price: 41800, electric: true, colour: 'Silver' },
{ make: 'Nissan', model: 'Leaf', price: 28350, electric: true, colour: 'Green' },
{ make: 'Honda', model: 'CR-V', price: 30000, electric: false, colour: 'Red' },
{ make: 'Audi', model: 'e-tron', price: 74800, electric: true, colour: 'Blue' },
{ make: 'Kia', model: 'EV6', price: 42600, electric: true, colour: 'White' },
{ make: 'Porsche', model: 'Taycan', price: 86700, electric: true, colour: 'Black' },
{ make: 'Chevrolet', model: 'Silverado', price: 31000, electric: false, colour: 'Grey' },
]);
const [colDefs, setColDefs] = useState([
{ field: 'make', headerCheckboxSelection: true, checkboxSelection: true },
{ field: 'model' },
{ field: 'price', valueFormatter: p => '$' + p.value.toLocaleString() },
{ field: 'electric' },
{ field: 'colour' },
]);
const defaultColDef = useMemo(() => ({
filter: true,
floatingFilter: true,
sortable: true,
resizable: true,
flex: 1,
minWidth: 100,
}), []);
const gridOptions = useMemo(() => ({
// General grid behavior
rowSelection: 'multiple',
rowMultiSelectWithClick: true,
suppressRowClickSelection: false, // Allow row click to select/deselect
animateRows: true, // Smooth row animations
// Pagination settings
pagination: true,
paginationPageSize: 5,
paginationPageSizeSelector: [5, 10, 20],
// Layout
domLayout: 'normal', // Grid will occupy its parent's dimensions
// Interaction
enableRangeSelection: true, // Enable cell range selection
// Callbacks (can also be passed as props directly)
// onGridReady: (params) => { console.log('Grid is ready via gridOptions!', params); },
// onRowClicked: (event) => { console.log('Row clicked:', event.data); }
}), []);
const onGridReady = useCallback((params) => {
// Access Grid API and Column API
console.log('Grid is ready via prop!');
gridRef.current.api.sizeColumnsToFit(); // Example: auto-fit columns on load
}, []);
const onRowClicked = useCallback((event) => {
console.log('Row data:', event.data);
}, []);
const onSelectionChanged = useCallback(() => {
const selectedRows = gridRef.current.api.getSelectedRows();
console.log('Selected Rows:', selectedRows);
}, []);
return (
<div className="ag-theme-quartz" style={{ height: 500, width: '100%' }}>
<h2>Advanced Cars Grid</h2>
<AgGridReact
ref={gridRef}
rowData={rowData}
columnDefs={colDefs}
defaultColDef={defaultColDef} // defaultColDef is usually passed as a separate prop
gridOptions={gridOptions} // All other configurations
onGridReady={onGridReady}
onRowClicked={onRowClicked}
onSelectionChanged={onSelectionChanged}
/>
</div>
);
};
export default AdvancedGridComponent;
In this example, we've configured default behaviors for all columns, enabled multi-select row selection, pagination, row animations, and cell range selection. We also use onGridReady to automatically size columns to fit the grid width.
Best Practices for Grid Options
- Memoize Complex Options: Use
useMemofor yourgridOptionsobject to prevent unnecessary re-creations and optimize performance, especially if it contains functions or is built dynamically. - Separate Concerns: While you can put everything into
gridOptions, consider passingrowData,columnDefs, and frequently changing event handlers (likeonGridReady,onCellClicked) as direct props to<AgGridReact>. This often integrates better with React's update mechanisms. - Use `defaultColDef` Wisely: Leverage
defaultColDefto apply common settings across many columns, then override them for specific columns when needed. - Explore the Documentation: AG-Grid has extensive documentation. Whenever you need a specific feature, check the "Grid Options" section for the available properties and their usage.
Conclusion
Grid options are the heart of AG-Grid's configurability, offering a robust mechanism to tailor every aspect of your data grid. By mastering these options, you gain the power to create highly functional, user-friendly, and visually appealing grids that perfectly fit the requirements of your React applications. Experiment with different settings, combine features, and unlock the full potential of AG-Grid.
Stay tuned for the next part of our series, where we'll delve into even more advanced topics!