Row selection
Set enableRowSelection: true to add a leading checkbox column. When rows are selected, a selection alert banner appears showing the current count.
enableRowSelection accepts a boolean or a (row) => boolean predicate (standard TanStack), so you can allow selecting only certain rows.
Stable selection keys
Always provide getRowId so selection keys stay stable across re-renders,
sorting, and pagination. Without it, selection is keyed by row index and can
drift.
row-selection
Multi-row selection with a select-all checkbox in the header.
ID | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Ava | Thompson | Owner | Engineering | active | 22 | $45,000 | Jan 2, 2023 | 0% | |||
| Liam | Nguyen | Admin | Marketing | inactive | 25 | $47,137 | Jan 13, 2023 | 9% | |||
| Noah | Silva | Editor | Design | pending | 28 | $49,274 | Jan 24, 2023 | 18% | |||
| Emma | Carter | Viewer | Sales | active | 31 | $51,411 | Feb 4, 2023 | 27% | |||
| Olivia | Rossi | Owner | Support | inactive | 34 | $53,548 | Feb 15, 2023 | 36% | |||
| William | Walker | Admin | Engineering | pending | 37 | $55,685 | Feb 26, 2023 | 45% | |||
| Sophia | Patel | Editor | Marketing | active | 40 | $57,822 | Mar 9, 2023 | 54% | |||
| James | Muller | Viewer | Design | inactive | 43 | $59,959 | Mar 20, 2023 | 63% | |||
| Isabella | Park | Owner | Sales | pending | 46 | $62,096 | Mar 31, 2023 | 72% | |||
| Lucas | Reyes | Admin | Support | active | 49 | $64,233 | Apr 11, 2023 | 81% | |||
| $4,120,536 |
const table = useDataTable({
data,
columns,
getRowId: (row) => row.id,
enableRowSelection: true,
})
return <DataTable table={table} />
Read the current selection at any time:
const selected = table.getState().rowSelection
Or control it from your own state:
const table = useDataTable({
data,
columns,
getRowId: (row) => row.id,
enableRowSelection: true,
state: { rowSelection },
onRowSelectionChange: setRowSelection,
})
You can also gate selection per row with a predicate:
enableRowSelection: (row) => row.original.status !== "archived"
single-selection
For radio-like single selection (no select-all checkbox), add enableMultiRowSelection: false.
ID | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Ava | Thompson | Owner | Engineering | active | 22 | $45,000 | Jan 2, 2023 | 0% | |||
| Liam | Nguyen | Admin | Marketing | inactive | 25 | $47,137 | Jan 13, 2023 | 9% | |||
| Noah | Silva | Editor | Design | pending | 28 | $49,274 | Jan 24, 2023 | 18% | |||
| Emma | Carter | Viewer | Sales | active | 31 | $51,411 | Feb 4, 2023 | 27% | |||
| Olivia | Rossi | Owner | Support | inactive | 34 | $53,548 | Feb 15, 2023 | 36% | |||
| William | Walker | Admin | Engineering | pending | 37 | $55,685 | Feb 26, 2023 | 45% | |||
| Sophia | Patel | Editor | Marketing | active | 40 | $57,822 | Mar 9, 2023 | 54% | |||
| James | Muller | Viewer | Design | inactive | 43 | $59,959 | Mar 20, 2023 | 63% | |||
| Isabella | Park | Owner | Sales | pending | 46 | $62,096 | Mar 31, 2023 | 72% | |||
| Lucas | Reyes | Admin | Support | active | 49 | $64,233 | Apr 11, 2023 | 81% | |||
| $4,120,536 |
const table = useDataTable({
data,
columns,
getRowId: (row) => row.id,
enableRowSelection: true,
enableMultiRowSelection: false,
})
return <DataTable table={table} />
Select-all behavior
The selection column header carries a select-all checkbox. selectAllMode controls its scope — "page" (default) toggles the current page, "all" toggles every row across pages. Set enableSelectAll: false to hide the header checkbox entirely.
const table = useDataTable({
data,
columns,
getRowId: (row) => row.id,
enableRowSelection: true,
selectAllMode: "all", // "page" | "all"
enableSelectAll: true,
})
Relevant options
| Prop | Type | Default | Description |
|---|---|---|---|
enableSelectAll? | boolean | true | Show the select-all checkbox in the selection column header. Default true. |
selectAllMode? | "page" | "all" | "page" | Select-all scope for the header checkbox: the current page ("page", default) or every row ("all"). |