Sometimes, we want to add table rows that are selectable on click with React Table
In this article, we’ll look at how to add table rows that are selectable on click with React Table.
Add Table Rows that are Selectable on Click with React Table
To add table rows that are selectable on click with React Table, we can customize the columns to add a checkbox to the left of the other items.
Then we can pass props to that to make it select the rows.
For instance, we can write:
import React from "react";
import { useTable, useRowSelect } from "react-table";
import namor from "namor";
const range = (len) => {
const arr = [];
for (let i = 0; i < len; i++) {
arr.push(i);
}
return arr;
};
const newPerson = () => {
return {
firstName: namor.generate({ words: 1, numbers: 0 }),
lastName: namor.generate({ words: 1, numbers: 0 }),
age: Math.floor(Math.random() * 30)
};
};
const makeData = (...lens) => {
const makeDataLevel = (depth = 0) => {
const len = lens[depth];
return range(len).map((d) => {
return {
...newPerson(),
subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined
};
});
};
return makeDataLevel();
};
const IndeterminateCheckbox = React.forwardRef(
({ indeterminate, ...rest }, ref) => {
const defaultRef = React.useRef();
const resolvedRef = ref || defaultRef;
React.useEffect(() => {
resolvedRef.current.indeterminate = indeterminate;
}, [resolvedRef, indeterminate]);
return (
<>
<input type="checkbox" ref={resolvedRef} {...rest} />
</>
);
}
);
function Table({ columns, data }) {
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow,
selectedFlatRows,
state: { selectedRowIds }
} = useTable(
{
columns,
data
},
useRowSelect,
(hooks) => {
hooks.visibleColumns.push((columns) => [
{
id: "selection",
Header: ({ getToggleAllRowsSelectedProps }) => (
<div>
<IndeterminateCheckbox {...getToggleAllRowsSelectedProps()} />
</div>
),
Cell: ({ row }) => (
<div>
<IndeterminateCheckbox {...row.getToggleRowSelectedProps()} />
</div>
)
},
...columns
]);
}
);
return (
<>
<table {...getTableProps()}>
<thead>
{headerGroups.map((headerGroup) => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map((column) => (
<th {...column.getHeaderProps()}>{column.render("Header")}</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{rows.slice(0, 10).map((row, i) => {
prepareRow(row);
return (
<tr {...row.getRowProps()}>
{row.cells.map((cell) => {
return (
<td {...cell.getCellProps()}>{cell.render("Cell")}</td>
);
})}
</tr>
);
})}
</tbody>
</table>
<p>Selected Rows: {Object.keys(selectedRowIds).length}</p>
<pre>
<code>
{JSON.stringify(
{
selectedRowIds: selectedRowIds,
"selectedFlatRows[].original": selectedFlatRows.map(
(d) => d.original
)
},
null,
2
)}
</code>
</pre>
</>
);
}
export default function App() {
const columns = React.useMemo(
() => [
{
Header: "Name",
columns: [
{
Header: "First Name",
accessor: "firstName"
},
{
Header: "Last Name",
accessor: "lastName"
}
]
},
{
Header: "Info",
columns: [
{
Header: "Age",
accessor: "age"
}
]
}
],
[]
);
const data = React.useMemo(() => makeData(10, 3), []);
return <Table columns={columns} data={data} />;
}
We create some data with the makeData
function, which calls newPerson
to return some randomly generated data.
Then we create the IndeterminateCheckbox
component that renders a checkbox that is assigned the ref that we get from the 2nd parameter.
We also pass in the rest
props from the first parameter.
This will let us select rows with the checkbox.
Then in the Table
component, we render the data.
We set the Header
property to a function that renders the IndeterminateCheckbox
with the props that we get from getToggleAllRowProps
.
Likewise, we set the Cell
property to a function that renders the IndeterminateCheckbox
with the props that we get from getToggleRowSelectedProps
.
We put that before columns
so that it’ll be rendered on the leftmost column.
Then in the return
statement, we render the table contents.
selectedRowIds
has the IDs of the selected row.
And selectedFlatRows
has the data of the selected rows.
Conclusion
To add table rows that are selectable on click with React Table, we can customize the columns to add a checkbox to the left of the other items.
Then we can pass props to that to make it select the rows.