eact Data Grid (by Adazzle) is a powerful, feature-rich data grid component for React that provides Excel-like functionality with virtualization, sorting, filtering, and cell editing. It's designed to handle large datasets efficiently while maintaining smooth performance. This guide walks through creating interactive, performant data tables using React Data Grid, covering setup, configuration, and practical implementation patterns. This is part 5 of a series on using React Data Grid with React.
Prerequisites
Before you begin, ensure you have:
- Node.js version 16.0 or higher
- npm, yarn, or pnpm package manager
- A React project (version 16.8 or higher) with hooks support
- Basic understanding of React hooks (useState, useCallback)
- Familiarity with TypeScript (optional but recommended)
Installation
Install React Data Grid using your preferred package manager:
npm install react-data-grid
Or with yarn:
yarn add react-data-grid
Or with pnpm:
pnpm add react-data-grid
For TypeScript support, types are included in the package. Your package.json should include:
{
"dependencies": {
"react-data-grid": "^7.0.0",
"react": "^18.0.0",
"react-dom": "^18.0.0"
}
}
Project Setup
React Data Grid requires CSS styles to be imported. Add the styles to your main application file or component:
// src/index.js or src/App.jsx
import 'react-data-grid/lib/styles.css';
If you're using a module bundler that doesn't handle CSS imports, you may need to configure it or import the CSS in your HTML file.
First Example / Basic Usage
Let's create a basic data grid component. Create src/DataTable.jsx:
// src/DataTable.jsx
import React from 'react';
import { DataGrid } from 'react-data-grid';
import 'react-data-grid/lib/styles.css';
// Define the row type
interface Row {
id: number;
title: string;
count: number;
status: string;
}
// Define columns
const columns = [
{ key: 'id', name: 'ID', width: 80 },
{ key: 'title', name: 'Title', resizable: true },
{ key: 'count', name: 'Count', width: 100 },
{ key: 'status', name: 'Status', width: 120 }
];
// Sample data
const rows: Row[] = [
{ id: 0, title: 'Task 1', count: 10, status: 'Active' },
{ id: 1, title: 'Task 2', count: 5, status: 'Pending' },
{ id: 2, title: 'Task 3', count: 15, status: 'Active' },
{ id: 3, title: 'Task 4', count: 8, status: 'Completed' },
{ id: 4, title: 'Task 5', count: 20, status: 'Active' }
];
function DataTable() {
return (
<div style={{ height: 400, width: '100%' }}>
<DataGrid columns={columns} rows={rows} />
</div>
);
}
export default DataTable;
If you're not using TypeScript, you can use JavaScript:
// src/DataTable.jsx
import React from 'react';
import { DataGrid } from 'react-data-grid';
import 'react-data-grid/lib/styles.css';
const columns = [
{ key: 'id', name: 'ID', width: 80 },
{ key: 'title', name: 'Title', resizable: true },
{ key: 'count', name: 'Count', width: 100 },
{ key: 'status', name: 'Status', width: 120 }
];
const rows = [
{ id: 0, title: 'Task 1', count: 10, status: 'Active' },
{ id: 1, title: 'Task 2', count: 5, status: 'Pending' },
{ id: 2, title: 'Task 3', count: 15, status: 'Active' },
{ id: 3, title: 'Task 4', count: 8, status: 'Completed' },
{ id: 4, title: 'Task 5', count: 20, status: 'Active' }
];
function DataTable() {
return (
<div style={{ height: 400, width: '100%' }}>
<DataGrid columns={columns} rows={rows} />
</div>
);
}
export default DataTable;
Update your App.jsx:
// src/App.jsx
import React from 'react';
import DataTable from './DataTable';
import './App.css';
function App() {
return (
<div className="App" style={{ padding: '20px' }}>
<h1>React Data Grid Example</h1>
<DataTable />
</div>
);
}
export default App;
This creates a basic data grid with resizable columns. You can drag column borders to resize them.
Understanding the Basics
React Data Grid uses a column-based configuration where each column defines:
- key: Unique identifier that maps to a property in your row objects
- name: Display header text
- width: Column width in pixels (optional)
- resizable: Allow column resizing (default: false)
- sortable: Enable sorting (default: false)
- editable: Enable cell editing (default: false)
Key concepts:
- Columns: Define the structure and behavior of each column
- Rows: Array of data objects where each object represents a table row
- Virtualization: Automatically handles large datasets efficiently
- Row Key Getter: Function to provide unique identifiers for rows (important for selection and updates)
Here's an example with sorting and row selection:
// src/SortableTable.jsx
import React, { useState } from 'react';
import { DataGrid, SelectColumn } from 'react-data-grid';
import 'react-data-grid/lib/styles.css';
const columns = [
SelectColumn,
{ key: 'id', name: 'ID', width: 80, sortable: true },
{ key: 'name', name: 'Name', width: 200, sortable: true, resizable: true },
{ key: 'email', name: 'Email', width: 250, sortable: true },
{ key: 'role', name: 'Role', width: 150, sortable: true }
];
const rows = [
{ id: 1, name: 'John Doe', email: 'john@example.com', role: 'Admin' },
{ id: 2, name: 'Jane Smith', email: 'jane@example.com', role: 'User' },
{ id: 3, name: 'Bob Johnson', email: 'bob@example.com', role: 'User' },
{ id: 4, name: 'Alice Williams', email: 'alice@example.com', role: 'Admin' }
];
function SortableTable() {
const [sortColumns, setSortColumns] = useState([]);
const [selectedRows, setSelectedRows] = useState(new Set());
const sortedRows = React.useMemo(() => {
if (sortColumns.length === 0) return rows;
return [...rows].sort((a, b) => {
for (const sort of sortColumns) {
const aValue = a[sort.columnKey];
const bValue = b[sort.columnKey];
const comp = aValue < bValue ? -1 : aValue > bValue ? 1 : 0;
return sort.direction === 'ASC' ? comp : -comp;
}
return 0;
});
}, [sortColumns]);
return (
<div style={{ height: 400, width: '100%' }}>
<DataGrid
columns={columns}
rows={sortedRows}
rowKeyGetter={(row) => row.id}
selectedRows={selectedRows}
onSelectedRowsChange={setSelectedRows}
sortColumns={sortColumns}
onSortColumnsChange={setSortColumns}
/>
</div>
);
}
export default SortableTable;
Practical Example / Building Something Real
Let's build a comprehensive task management table with editing, filtering, and custom rendering:
// src/TaskManager.jsx
import React, { useState, useMemo } from 'react';
import { DataGrid } from 'react-data-grid';
import 'react-data-grid/lib/styles.css';
const columns = [
{
key: 'id',
name: 'ID',
width: 60,
frozen: true
},
{
key: 'title',
name: 'Title',
width: 200,
resizable: true,
editable: true,
sortable: true
},
{
key: 'priority',
name: 'Priority',
width: 120,
editable: true,
renderCell: ({ row }) => {
const colors = {
High: '#dc3545',
Medium: '#ffc107',
Low: '#28a745'
};
return (
<span style={{
color: colors[row.priority] || '#6c757d',
fontWeight: 'bold'
}}>
{row.priority}
</span>
);
},
renderEditCell: ({ row, onRowChange }) => {
return (
<select
value={row.priority}
onChange={(e) => onRowChange({ ...row, priority: e.target.value })}
style={{ width: '100%', padding: '4px' }}
>
<option value="High">High</option>
<option value="Medium">Medium</option>
<option value="Low">Low</option>
</select>
);
}
},
{
key: 'status',
name: 'Status',
width: 120,
editable: true,
renderCell: ({ row }) => {
const statusColors = {
'To Do': '#6c757d',
'In Progress': '#007bff',
'Done': '#28a745'
};
return (
<span style={{
color: statusColors[row.status] || '#6c757d',
fontWeight: 'bold'
}}>
{row.status}
</span>
);
}
},
{
key: 'assignee',
name: 'Assignee',
width: 150,
editable: true,
sortable: true
},
{
key: 'dueDate',
name: 'Due Date',
width: 120,
editable: true,
renderCell: ({ row }) => {
if (!row.dueDate) return '-';
const date = new Date(row.dueDate);
return date.toLocaleDateString();
},
renderEditCell: ({ row, onRowChange }) => {
return (
<input
type="date"
value={row.dueDate || ''}
onChange={(e) => onRowChange({ ...row, dueDate: e.target.value })}
style={{ width: '100%', padding: '4px' }}
/>
);
}
}
];
const initialRows = [
{ id: 1, title: 'Implement user authentication', priority: 'High', status: 'In Progress', assignee: 'John Doe', dueDate: '2024-12-31' },
{ id: 2, title: 'Design database schema', priority: 'Medium', status: 'Done', assignee: 'Jane Smith', dueDate: '2024-12-15' },
{ id: 3, title: 'Write API documentation', priority: 'Low', status: 'To Do', assignee: 'Bob Johnson', dueDate: '2025-01-10' },
{ id: 4, title: 'Setup CI/CD pipeline', priority: 'High', status: 'In Progress', assignee: 'Alice Williams', dueDate: '2024-12-20' },
{ id: 5, title: 'Code review and testing', priority: 'Medium', status: 'To Do', assignee: 'John Doe', dueDate: '2025-01-05' }
];
function TaskManager() {
const [rows, setRows] = useState(initialRows);
const [sortColumns, setSortColumns] = useState([]);
const [filter, setFilter] = useState('');
const filteredRows = useMemo(() => {
if (!filter) return rows;
const lowerFilter = filter.toLowerCase();
return rows.filter(row =>
Object.values(row).some(value =>
String(value).toLowerCase().includes(lowerFilter)
)
);
}, [rows, filter]);
const sortedRows = useMemo(() => {
if (sortColumns.length === 0) return filteredRows;
return [...filteredRows].sort((a, b) => {
for (const sort of sortColumns) {
const aValue = a[sort.columnKey];
const bValue = b[sort.columnKey];
const comp = aValue < bValue ? -1 : aValue > bValue ? 1 : 0;
return sort.direction === 'ASC' ? comp : -comp;
}
return 0;
});
}, [filteredRows, sortColumns]);
const handleRowChange = (newRow) => {
setRows(rows.map(row => row.id === newRow.id ? newRow : row));
};
return (
<div style={{ padding: '20px' }}>
<h2>Task Management</h2>
<div style={{ marginBottom: '16px' }}>
<input
type="text"
placeholder="Search tasks..."
value={filter}
onChange={(e) => setFilter(e.target.value)}
style={{
padding: '8px',
width: '300px',
border: '1px solid #ddd',
borderRadius: '4px'
}}
/>
</div>
<div style={{ height: 500, width: '100%', border: '1px solid #ddd' }}>
<DataGrid
columns={columns}
rows={sortedRows}
rowKeyGetter={(row) => row.id}
onRowsChange={setRows}
sortColumns={sortColumns}
onSortColumnsChange={setSortColumns}
defaultColumnOptions={{
resizable: true,
sortable: true
}}
/>
</div>
</div>
);
}
export default TaskManager;
This example demonstrates:
- Editable cells with custom editors (dropdown, date picker)
- Custom cell rendering with conditional styling
- Frozen columns (ID column stays fixed)
- Sorting functionality
- Global search/filtering
- Row updates with state management
- Resizable columns
Common Issues / Troubleshooting
Styles not loading: Make sure you've imported
'react-data-grid/lib/styles.css'in your component or main entry file. Without styles, the grid won't display correctly.Row selection not working: Implement
rowKeyGetterprop to provide unique identifiers for each row. This is required for selection features.Sorting not working: Ensure you're managing
sortColumnsstate and implementing the sorting logic yourself, or use a library that handles it. React Data Grid doesn't sort automatically.Performance with large datasets: React Data Grid uses virtualization by default, but for very large datasets (10,000+ rows), consider implementing server-side pagination or filtering.
TypeScript errors: Make sure you're using the correct types from
react-data-grid. The library exports TypeScript types, so ensure your column and row types match the expected interfaces.
Next Steps
Now that you understand React Data Grid basics:
- Explore advanced features like row grouping and aggregation
- Implement custom cell editors and renderers
- Add row expansion for nested data
- Learn about column pinning and reordering
- Implement server-side data loading
- Add export functionality (CSV, Excel)
- Check the official repository: https://github.com/adazzle/react-data-grid
- Look for part 6 of this series for more advanced topics
Summary
You've learned how to set up React Data Grid and create interactive data tables with sorting, filtering, editing, and custom rendering. The library provides excellent performance for large datasets through virtualization and offers extensive customization options for building sophisticated data management interfaces.
Top comments (0)