Want to skip to the implementation? Check out these examples:
The column visibility feature allows table columns to be hidden or shown dynamically. In previous versions of react-table, this feature was a static property on a column, but in v8, there is a dedicated columnVisibility state and APIs for managing column visibility dynamically.
The columnVisibility state is a map of column IDs to boolean values. A column will be hidden if its ID is present in the map and the value is false. If the column ID is not present in the map, or the value is true, the column will be shown.
const [columnVisibility, setColumnVisibility] = useState({
columnId1: true,
columnId2: false, //hide this column by default
columnId3: true,
});
const table = useReactTable({
//...
state: {
columnVisibility,
//...
},
onColumnVisibilityChange: setColumnVisibility,
});
const [columnVisibility, setColumnVisibility] = useState({
columnId1: true,
columnId2: false, //hide this column by default
columnId3: true,
});
const table = useReactTable({
//...
state: {
columnVisibility,
//...
},
onColumnVisibilityChange: setColumnVisibility,
});
Alternatively, if you don't need to manage the column visibility state outside of the table, you can still set the initial default column visibility state using the initialState option.
Note: If columnVisibility is provided to both initialState and state, the state initialization will take precedence and initialState will be ignored. Do not provide columnVisibility to both initialState and state, only one or the other.
const table = useReactTable({
//...
initialState: {
columnVisibility: {
columnId1: true,
columnId2: false, //hide this column by default
columnId3: true,
},
//...
},
});
const table = useReactTable({
//...
initialState: {
columnVisibility: {
columnId1: true,
columnId2: false, //hide this column by default
columnId3: true,
},
//...
},
});
By default, all columns can be hidden or shown. If you want to prevent certain columns from being hidden, you set the enableHiding column option to false for those columns.
const columns = [
{
header: 'ID',
accessorKey: 'id',
enableHiding: false, // disable hiding for this column
},
{
header: 'Name',
accessor: 'name', // can be hidden
},
];
const columns = [
{
header: 'ID',
accessorKey: 'id',
enableHiding: false, // disable hiding for this column
},
{
header: 'Name',
accessor: 'name', // can be hidden
},
];
There are several column API methods that are useful for rendering column visibility toggles in the UI.
{table.getAllColumns().map((column) => (
<label key={column.id}>
<input
checked={column.getIsVisible()}
disabled={!column.getCanHide()}
onChange={column.getToggleVisibilityHandler()}
type="checkbox"
/>
{column.columnDef.header}
</label>
))}
{table.getAllColumns().map((column) => (
<label key={column.id}>
<input
checked={column.getIsVisible()}
disabled={!column.getCanHide()}
onChange={column.getToggleVisibilityHandler()}
type="checkbox"
/>
{column.columnDef.header}
</label>
))}
When you render your header, body, and footer cells, there are a lot of API options available. You may see APIs like table.getAllLeafColumns and row.getAllCells, but if you use these APIs, they will not take column visibility into account. Instead, you need to use the "visible" variants of these APIs, such as table.getVisibleLeafColumns and row.getVisibleCells.
<table>
<thead>
<tr>
{table.getVisibleLeafColumns().map((column) => ( // takes column visibility into account
//
))}
</tr>
</thead>
<tbody>
{table.getRowModel().rows.map((row) => (
<tr key={row.id}>
{row.getVisibleCells().map((cell) => ( // takes column visibility into account
//
))}
</tr>
))}
</tbody>
</table>
<table>
<thead>
<tr>
{table.getVisibleLeafColumns().map((column) => ( // takes column visibility into account
//
))}
</tr>
</thead>
<tbody>
{table.getRowModel().rows.map((row) => (
<tr key={row.id}>
{row.getVisibleCells().map((cell) => ( // takes column visibility into account
//
))}
</tr>
))}
</tbody>
</table>
If you are using the Header Group APIs, they will already take column visibility into account.
Your weekly dose of JavaScript news. Delivered every Monday to over 100,000 devs, for free.