Column reordering
Set reorder: true on any column definition to make that header draggable. Users drag a header cell left or right to swap it with the column it's dropped on. The onColumnOrderChange callback fires after every swap with the updated column array.
On touch devices, press and hold a reorderable header for a moment to grab it, then drag to reorder. The short hold keeps a normal swipe scrolling the table instead of starting a drag. Group reorder works the same way.
Drag to reorder columns
Grab any column header and drag it to a new position. The current order is shown below the table.
Drag any column header to reorder it.
Current order: name → role → department → salary
import { useState } from 'react';
import DataTable, { type TableColumn } from 'react-data-table-component';
interface Employee {
id: number;
name: string;
role: string;
department: string;
salary: number;
}
const data: Employee[] = [
{ id: 1, name: 'Aria Chen', role: 'Engineering Lead', department: 'Engineering', salary: 155000 },
{ id: 2, name: 'Marcus Webb', role: 'Product Manager', department: 'Product', salary: 132000 },
{ id: 3, name: 'Priya Kapoor', role: 'Senior Designer', department: 'Design', salary: 118000 },
{ id: 4, name: 'Jordan Ellis', role: 'Data Scientist', department: 'Analytics', salary: 143000 },
{ id: 5, name: 'Sam Rivera', role: 'DevOps Engineer', department: 'Engineering', salary: 128000 },
];
const initialColumns: TableColumn<Employee>[] = [
{ id: 'name', name: 'Name', selector: r => r.name, sortable: true, reorder: true },
{ id: 'role', name: 'Role', selector: r => r.role, reorder: true },
{ id: 'department', name: 'Department', selector: r => r.department, sortable: true, reorder: true },
{
id: 'salary',
name: 'Salary',
selector: r => r.salary,
sortable: true,
reorder: true,
format: r => `$${r.salary.toLocaleString()}`,
right: true,
},
];
export default function App() {
const [columns, setColumns] = useState(initialColumns);
return <DataTable columns={columns} data={data} onColumnOrderChange={setColumns} highlightOnHover />;
}Enabling reorder per column
reorder is a per-column flag, not a table-level prop. Columns without it are fixed in place. This lets you pin identity columns (e.g. a row number or name) while keeping the rest draggable.
const columns: TableColumn<Employee>[] = [
{ id: 'name', name: 'Name', selector: r => r.name /* no reorder — pinned */ },
{ id: 'role', name: 'Role', selector: r => r.role, reorder: true },
{ id: 'dept', name: 'Dept', selector: r => r.dept, reorder: true },
{ id: 'salary', name: 'Salary', selector: r => r.salary, reorder: true },
];Persisting column order
Column order is in-memory only and resets on remount. Persist it vialocalStorage by saving the ordered column IDs and restoring them on init:
const STORAGE_KEY = 'my-table-col-order';
function applyOrder(cols: TableColumn<Employee>[], order: string[]) {
if (!order.length) return cols;
return [...cols].sort((a, b) => order.indexOf(String(a.id)) - order.indexOf(String(b.id)));
}
function loadOrder(): string[] {
try {
return JSON.parse(localStorage.getItem(STORAGE_KEY) ?? '[]');
} catch {
return [];
}
}
export default function App() {
const [columns, setColumns] = useState(() => applyOrder(initialColumns, loadOrder()));
function handleOrderChange(next: TableColumn<Employee>[]) {
setColumns(next);
localStorage.setItem(STORAGE_KEY, JSON.stringify(next.map(c => String(c.id))));
}
return <DataTable columns={columns} data={data} onColumnOrderChange={handleOrderChange} />;
}Reordering column groups
When using columnGroups, set reorder: true on each group instead of on individual columns. Dragging a group header moves all of its member columns as a single block, keeping spans intact. Use onColumnGroupOrderChangeto receive both the new group order and the matching column array.
Drag to reorder groups
Grab a group header (Employee or Compensation) and drag it to swap the two groups.
Drag a group header to move the whole group. Drag an individual column header to reorder it within its group.
Group order: Employee → Compensation
import { useState } from 'react';
import DataTable, { type TableColumn, type ColumnGroup } from 'react-data-table-component';
const columns: TableColumn<Row>[] = [
{ id: 'first', name: 'First name', selector: r => r.firstName, sortable: true },
{ id: 'last', name: 'Last name', selector: r => r.lastName, sortable: true },
{ id: 'dept', name: 'Department', selector: r => r.department, sortable: true },
{
id: 'base',
name: 'Base salary',
selector: r => r.baseSalary,
sortable: true,
right: true,
format: r => `$${r.baseSalary.toLocaleString()}`,
},
{
id: 'bonus',
name: 'Bonus',
selector: r => r.bonus,
sortable: true,
right: true,
format: r => `$${r.bonus.toLocaleString()}`,
},
];
const initialGroups: ColumnGroup[] = [
{ name: 'Employee', columnIds: ['first', 'last', 'dept'], reorder: true },
{ name: 'Compensation', columnIds: ['base', 'bonus'], reorder: true },
];
export default function App() {
const [cols, setCols] = useState(columns);
const [groups, setGroups] = useState(initialGroups);
return (
<DataTable
columns={cols}
data={data}
columnGroups={groups}
onColumnOrderChange={setCols}
onColumnGroupOrderChange={(nextGroups, nextCols) => {
setGroups(nextGroups);
setCols(nextCols);
}}
highlightOnHover
/>
);
}You can combine both — set reorder: true on columns AND on groups. Column drag is automatically restricted to within the same group, so spans stay correct. Group drag moves the entire block. This mirrors the AG Grid reorder experience.
const columns: TableColumn<Employee>[] = [
{ id: 'first', name: 'First name', selector: r => r.firstName, sortable: true, reorder: true },
{ id: 'last', name: 'Last name', selector: r => r.lastName, sortable: true, reorder: true },
{ id: 'dept', name: 'Department', selector: r => r.department, sortable: true, reorder: true },
{ id: 'base', name: 'Base salary', selector: r => r.baseSalary, sortable: true, reorder: true },
{ id: 'bonus', name: 'Bonus', selector: r => r.bonus, sortable: true, reorder: true },
];
const columnGroups: ColumnGroup[] = [
{ name: 'Employee', columnIds: ['first', 'last', 'dept'], reorder: true },
{ name: 'Compensation', columnIds: ['base', 'bonus'], reorder: true },
];Prop reference
| Prop | Type | Default | Description |
|---|---|---|---|
onColumnOrderChange | (columns: TableColumn<T>[]) => void | - | Called after a drag-to-reorder column operation with the new column order. |
onColumnGroupOrderChange | (groups: ColumnGroup[], columns: TableColumn<T>[]) => void | - | Called after a group drag-reorder with the new group order and the matching updated column order. |
Set reorder: true on each TableColumn(or ColumnGroup) you want to be draggable.