Skip to main content

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:
1

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';
2

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;
}
3

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.
4

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()
  }
];
5

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

1

Explore Advanced Features

Learn about column resizing, grouping, frozen columns, and more in the API Reference.
2

Customize Appearance

Use CSS variables to customize colors, spacing, and other visual properties.
3

Add Custom Renderers

Create custom cell renderers, editors, and row components for complete control.
4

Optimize Performance

Learn best practices for handling large datasets and optimizing re-renders.

Common Patterns

Custom Cell Formatters

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.

Build docs developers (and LLMs) love