Skip to main content

Overview

Columns define the structure and behavior of your data grid. Each column configuration controls how data is displayed, edited, and interacted with.

Basic Column Structure

Every column requires two essential properties:
import { DataGrid, type Column } from 'react-data-grid';

interface Row {
  id: number;
  title: string;
}

const columns: readonly Column<Row>[] = [
  { key: 'id', name: 'ID' },
  { key: 'title', name: 'Title' }
];

Column Properties

Required Properties

key
string
required
A unique key to distinguish each column. Used to access the row data.
name
string | ReactElement
required
The name of the column. Displayed in the header cell by default.

Width Configuration

width
number | string
default:"auto"
Column width. Can be pixels, percentage, or CSS grid values.
// Fixed width in pixels
{ key: 'id', name: 'ID', width: 80 }

// Percentage width
{ key: 'name', name: 'Name', width: '30%' }

// Auto-sized to content
{ key: 'description', name: 'Description', width: 'max-content' }
minWidth
number
default:50
Minimum column width in pixels.
maxWidth
number
Maximum column width in pixels.
resizable
boolean
default:false
Enable column resizing by dragging the column edge.
const columns: Column<Row>[] = [
  {
    key: 'name',
    name: 'Name',
    resizable: true,
    minWidth: 100,
    maxWidth: 400
  }
];

Behavior Properties

frozen
boolean
default:false
Pin the column to the left side (or right in RTL mode) during horizontal scrolling.
const columns: Column<Row>[] = [
  { key: 'id', name: 'ID', frozen: true, width: 80 },
  { key: 'name', name: 'Name', frozen: true },
  { key: 'email', name: 'Email' }
];
sortable
boolean
default:false
Enable sorting for this column. Click the header to toggle sort direction.
draggable
boolean
default:false
Enable column reordering by dragging the header.
sortDescendingFirst
boolean
default:false
Start with descending order on first sort instead of ascending.

Styling Properties

cellClass
string | ((row: TRow) => string | null)
CSS class name(s) for cells. Can be static or dynamic based on row data.
const columns: Column<Row>[] = [
  {
    key: 'status',
    name: 'Status',
    cellClass: (row) => `status-${row.status}`
  },
  {
    key: 'price',
    name: 'Price',
    cellClass: 'text-right'
  }
];
headerCellClass
string
CSS class name(s) for the header cell.
summaryCellClass
string | ((row: TSummaryRow) => string | null)
CSS class name(s) for summary row cells.

Custom Renderers

renderCell
(props: RenderCellProps<TRow, TSummaryRow>) => ReactNode
Custom function to render cell content.
import type { RenderCellProps } from 'react-data-grid';

const columns: Column<Row>[] = [
  {
    key: 'avatar',
    name: 'Avatar',
    renderCell({ row }: RenderCellProps<Row>) {
      return <img src={row.avatarUrl} alt={row.name} />;
    }
  }
];
renderHeaderCell
(props: RenderHeaderCellProps<TRow, TSummaryRow>) => ReactNode
Custom function to render the header cell content.
import { renderHeaderCell, type Column } from 'react-data-grid';

const columns: Column<Row>[] = [
  {
    key: 'name',
    name: 'Name',
    sortable: true,
    renderHeaderCell
  }
];
renderSummaryCell
(props: RenderSummaryCellProps<TSummaryRow, TRow>) => ReactNode
Custom function to render summary row cells.
renderGroupCell
(props: RenderGroupCellProps<TRow, TSummaryRow>) => ReactNode
Custom function to render group cells when using TreeDataGrid.

Column Spanning

colSpan
(args: ColSpanArgs<TRow, TSummaryRow>) => number | undefined
Function to determine how many columns this cell should span.
const columns: Column<Row>[] = [
  {
    key: 'title',
    name: 'Title',
    colSpan(args) {
      if (args.type === 'ROW' && args.row.isFullWidth) {
        return 5; // Span 5 columns
      }
      return undefined;
    }
  }
];

Column Groups

Group multiple columns under a common header:
import type { ColumnOrColumnGroup } from 'react-data-grid';

const columns: readonly ColumnOrColumnGroup<Row>[] = [
  {
    name: 'Personal Info',
    children: [
      { key: 'firstName', name: 'First Name' },
      { key: 'lastName', name: 'Last Name' }
    ]
  },
  {
    name: 'Contact',
    children: [
      { key: 'email', name: 'Email' },
      { key: 'phone', name: 'Phone' }
    ]
  }
];
Column groups are not supported in TreeDataGrid. Use only with DataGrid.

Default Column Options

Apply default settings to all columns:
<DataGrid
  columns={columns}
  rows={rows}
  defaultColumnOptions={{
    minWidth: 100,
    resizable: true,
    sortable: true,
    draggable: true
  }}
/>

Performance Tips

Passing a new columns array triggers a full grid re-render. Always memoize with useMemo or define outside the component.
import { useMemo } from 'react';
import { DataGrid, type Column } from 'react-data-grid';

function MyGrid() {
  const columns = useMemo<readonly Column<Row>[]>(() => [
    { key: 'id', name: 'ID' },
    { key: 'title', name: 'Title' }
  ], []);

  return <DataGrid columns={columns} rows={rows} />;
}

TypeScript Types

interface Column<TRow, TSummaryRow = unknown> {
  readonly name: string | ReactElement;
  readonly key: string;
  readonly width?: Maybe<number | string>;
  readonly minWidth?: Maybe<number>;
  readonly maxWidth?: Maybe<number>;
  readonly cellClass?: Maybe<string | ((row: TRow) => Maybe<string>)>;
  readonly headerCellClass?: Maybe<string>;
  readonly summaryCellClass?: Maybe<string | ((row: TSummaryRow) => Maybe<string>)>;
  readonly renderCell?: Maybe<(props: RenderCellProps<TRow, TSummaryRow>) => ReactNode>;
  readonly renderHeaderCell?: Maybe<(props: RenderHeaderCellProps<TRow, TSummaryRow>) => ReactNode>;
  readonly renderSummaryCell?: Maybe<(props: RenderSummaryCellProps<TSummaryRow, TRow>) => ReactNode>;
  readonly renderGroupCell?: Maybe<(props: RenderGroupCellProps<TRow, TSummaryRow>) => ReactNode>;
  readonly renderEditCell?: Maybe<(props: RenderEditCellProps<TRow, TSummaryRow>) => ReactNode>;
  readonly editable?: Maybe<boolean | ((row: TRow) => boolean)>;
  readonly colSpan?: Maybe<(args: ColSpanArgs<TRow, TSummaryRow>) => Maybe<number>>;
  readonly frozen?: Maybe<boolean>;
  readonly resizable?: Maybe<boolean>;
  readonly sortable?: Maybe<boolean>;
  readonly draggable?: Maybe<boolean>;
  readonly sortDescendingFirst?: Maybe<boolean>;
  readonly editorOptions?: Maybe<{
    readonly displayCellContent?: Maybe<boolean>;
    readonly commitOnOutsideClick?: Maybe<boolean>;
    readonly closeOnExternalRowChange?: Maybe<boolean>;
  }>;
}

Build docs developers (and LLMs) love