Quick Start
This guide will walk you through creating a fully functional data grid with sorting, editing, and row selection.
Basic Grid
Let’s start with a simple example that displays a list of tasks:
Import the necessary components
Import the DataGrid component and the required types: import 'react-data-grid/lib/styles.css' ;
import { DataGrid , type Column } from 'react-data-grid' ;
Define your row type
Create a TypeScript interface for your data: interface Row {
id : number ;
title : string ;
client : string ;
area : string ;
progress : number ;
startDate : number ;
endDate : number ;
}
Configure columns
Define the columns for your grid: const columns : readonly Column < Row >[] = [
{ key: 'id' , name: 'ID' , frozen: true },
{ key: 'title' , name: 'Task' },
{ key: 'client' , name: 'Client' },
{ key: 'area' , name: 'Area' },
{ key: 'progress' , name: 'Progress' }
];
The frozen: true property pins the column to the left during horizontal scrolling.
Prepare your data
Create some sample rows: const rows : readonly Row [] = [
{
id: 1 ,
title: 'Design Homepage' ,
client: 'Acme Corp' ,
area: 'Design' ,
progress: 75 ,
startDate: Date . now (),
endDate: Date . now ()
},
{
id: 2 ,
title: 'API Integration' ,
client: 'Tech Solutions' ,
area: 'Development' ,
progress: 50 ,
startDate: Date . now (),
endDate: Date . now ()
}
];
Render the grid
Create your component and render the DataGrid: function App () {
return < DataGrid columns = { columns } rows = { rows } /> ;
}
Adding Editing
Make your grid editable by adding the renderTextEditor to columns and handling changes:
import { useState } from 'react' ;
import { DataGrid , renderTextEditor , type Column } from 'react-data-grid' ;
function App () {
const [ rows , setRows ] = useState < Row []>( initialRows );
const columns : readonly Column < Row >[] = [
{ key: 'id' , name: 'ID' },
{
key: 'title' ,
name: 'Task' ,
renderEditCell: renderTextEditor
},
{
key: 'client' ,
name: 'Client' ,
renderEditCell: renderTextEditor
}
];
return (
< DataGrid
columns = { columns }
rows = { rows }
onRowsChange = { setRows }
/>
);
}
Double-click a cell to start editing. Press Enter to save or Escape to cancel.
Adding Row Selection
Enable row selection by adding the SelectColumn and managing selection state:
import { useState } from 'react' ;
import { DataGrid , SelectColumn , type Column } from 'react-data-grid' ;
interface Row {
id : number ;
title : string ;
client : string ;
}
function App () {
const [ rows ] = useState < Row []>( initialRows );
const [ selectedRows , setSelectedRows ] = useState < ReadonlySet < number >>(
() => new Set ()
);
const columns : readonly Column < Row >[] = [
SelectColumn ,
{ key: 'id' , name: 'ID' },
{ key: 'title' , name: 'Task' },
{ key: 'client' , name: 'Client' }
];
function rowKeyGetter ( row : Row ) {
return row . id ;
}
return (
< DataGrid
columns = { columns }
rows = { rows }
rowKeyGetter = { rowKeyGetter }
selectedRows = { selectedRows }
onSelectedRowsChange = { setSelectedRows }
/>
);
}
The rowKeyGetter function is required for row selection. It should return a unique identifier for each row.
Adding Sorting
Implement sorting by tracking sort columns and applying the sort to your data:
import { useState , useMemo } from 'react' ;
import { DataGrid , type Column , type SortColumn } from 'react-data-grid' ;
function App () {
const [ rows ] = useState < Row []>( initialRows );
const [ sortColumns , setSortColumns ] = useState < readonly SortColumn []>([]);
const columns : readonly Column < Row >[] = [
{ key: 'id' , name: 'ID' , sortable: true },
{ key: 'title' , name: 'Task' , sortable: true },
{ key: 'progress' , name: 'Progress' , sortable: true }
];
const sortedRows = useMemo (() => {
if ( sortColumns . length === 0 ) return rows ;
return [ ... rows ]. sort (( a , b ) => {
for ( const sort of sortColumns ) {
const aValue = a [ sort . columnKey as keyof Row ];
const bValue = b [ sort . columnKey as keyof Row ];
if ( aValue < bValue ) {
return sort . direction === 'ASC' ? - 1 : 1 ;
}
if ( aValue > bValue ) {
return sort . direction === 'ASC' ? 1 : - 1 ;
}
}
return 0 ;
});
}, [ rows , sortColumns ]);
return (
< DataGrid
columns = { columns }
rows = { sortedRows }
sortColumns = { sortColumns }
onSortColumnsChange = { setSortColumns }
/>
);
}
Click a column header to sort. Hold Ctrl/Cmd and click another header to add secondary sorting.
Complete Example
Here’s a full example combining editing, selection, and sorting:
import { useState , useMemo } from 'react' ;
import 'react-data-grid/lib/styles.css' ;
import {
DataGrid ,
SelectColumn ,
renderTextEditor ,
type Column ,
type SortColumn
} from 'react-data-grid' ;
interface Row {
id : number ;
title : string ;
client : string ;
progress : number ;
}
function App () {
const [ rows , setRows ] = useState < Row []>([
{ id: 1 , title: 'Design Homepage' , client: 'Acme Corp' , progress: 75 },
{ id: 2 , title: 'API Integration' , client: 'Tech Solutions' , progress: 50 },
{ id: 3 , title: 'Database Migration' , client: 'DataCo' , progress: 90 }
]);
const [ selectedRows , setSelectedRows ] = useState < ReadonlySet < number >>(
() => new Set ()
);
const [ sortColumns , setSortColumns ] = useState < readonly SortColumn []>([]);
const columns : readonly Column < Row >[] = [
SelectColumn ,
{ key: 'id' , name: 'ID' , sortable: true , frozen: true },
{
key: 'title' ,
name: 'Task' ,
sortable: true ,
renderEditCell: renderTextEditor
},
{
key: 'client' ,
name: 'Client' ,
sortable: true ,
renderEditCell: renderTextEditor
},
{
key: 'progress' ,
name: 'Progress' ,
sortable: true ,
renderCell ( props ) {
return (
<>
< progress max = { 100 } value = { props . row . progress } style = { { width: 50 } } />
{ ' ' }{ props . row . progress } %
</>
);
}
}
];
const sortedRows = useMemo (() => {
if ( sortColumns . length === 0 ) return rows ;
return [ ... rows ]. sort (( a , b ) => {
for ( const sort of sortColumns ) {
const aValue = a [ sort . columnKey as keyof Row ];
const bValue = b [ sort . columnKey as keyof Row ];
if ( aValue < bValue ) return sort . direction === 'ASC' ? - 1 : 1 ;
if ( aValue > bValue ) return sort . direction === 'ASC' ? 1 : - 1 ;
}
return 0 ;
});
}, [ rows , sortColumns ]);
function rowKeyGetter ( row : Row ) {
return row . id ;
}
return (
< DataGrid
columns = { columns }
rows = { sortedRows }
rowKeyGetter = { rowKeyGetter }
selectedRows = { selectedRows }
onSelectedRowsChange = { setSelectedRows }
onRowsChange = { setRows }
sortColumns = { sortColumns }
onSortColumnsChange = { setSortColumns }
style = { { height: 400 } }
/>
);
}
export default App ;
Key Concepts
Columns Define the structure and behavior of each column with the Column type
Rows Your data can be any object type - the grid is fully generic
Virtualization Only visible rows are rendered for optimal performance
Controlled State Sorting, selection, and editing are controlled by your component state
Next Steps
Explore Advanced Features
Learn about column resizing, grouping, frozen columns, and more in the API Reference.
Customize Appearance
Use CSS variables to customize colors, spacing, and other visual properties.
Add Custom Renderers
Create custom cell renderers, editors, and row components for complete control.
Optimize Performance
Learn best practices for handling large datasets and optimizing re-renders.
Common Patterns
Create rich cell content with custom render functions:
const columns : readonly Column < Row >[] = [
{
key: 'status' ,
name: 'Status' ,
renderCell ({ row }) {
return (
< span
style = { {
color: row . status === 'active' ? 'green' : 'red' ,
fontWeight: 'bold'
} }
>
{ row . status . toUpperCase () }
</ span >
);
}
}
];
Dynamic Row Heights
Set different heights for different rows:
function getRowHeight ( row : Row ) {
return row . isExpanded ? 100 : 35 ;
}
< DataGrid rowHeight = { getRowHeight } columns = { columns } rows = { rows } />
Column Resizing
Enable resizing for specific columns:
const columns : readonly Column < Row >[] = [
{
key: 'title' ,
name: 'Title' ,
resizable: true ,
minWidth: 100 ,
maxWidth: 400
}
];
Troubleshooting
If columns aren’t rendering correctly, ensure you’re memoizing the columns array with useMemo or defining it outside the component to avoid unnecessary re-renders.
Always provide a unique key for each column. The grid uses these keys to track column state internally.