Hooks for building lightweight, fast and extendable datagrids for React
—
React Table provides specialized layout plugins that enable different rendering approaches for tables. These layout systems optimize performance and provide specific styling capabilities for different use cases.
Provides absolute positioning layout for high-performance tables with fixed dimensions.
/**
* Adds absolute positioning layout to the table
* @param hooks - Hook registration object
*/
function useAbsoluteLayout(hooks: Hooks): void;Usage Example:
import React from 'react';
import { useTable, useAbsoluteLayout } from 'react-table';
function AbsoluteLayoutTable({ columns, data }) {
const defaultColumn = React.useMemo(
() => ({
width: 150,
}),
[]
);
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow,
totalColumnsWidth,
} = useTable(
{
columns,
data,
defaultColumn,
},
useAbsoluteLayout
);
return (
<div
{...getTableProps()}
style={{
position: 'relative',
width: totalColumnsWidth,
height: 400,
overflow: 'auto',
border: '1px solid black',
}}
>
<div>
{headerGroups.map(headerGroup => (
<div {...headerGroup.getHeaderGroupProps()} className="tr">
{headerGroup.headers.map(column => (
<div {...column.getHeaderProps()} className="th">
{column.render('Header')}
</div>
))}
</div>
))}
</div>
<div {...getTableBodyProps()}>
{rows.map(row => {
prepareRow(row);
return (
<div {...row.getRowProps()} className="tr">
{row.cells.map(cell => (
<div {...cell.getCellProps()} className="td">
{cell.render('Cell')}
</div>
))}
</div>
);
})}
</div>
</div>
);
}Provides block-level layout with explicit width management for consistent column sizing.
/**
* Adds block layout to the table
* @param hooks - Hook registration object
*/
function useBlockLayout(hooks: Hooks): void;Usage Example:
import React from 'react';
import { useTable, useBlockLayout, useResizeColumns } from 'react-table';
function BlockLayoutTable({ columns, data }) {
const defaultColumn = React.useMemo(
() => ({
minWidth: 30,
width: 150,
maxWidth: 400,
}),
[]
);
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow,
} = useTable(
{
columns,
data,
defaultColumn,
},
useBlockLayout,
useResizeColumns
);
return (
<div
{...getTableProps()}
style={{
display: 'inline-block',
border: '1px solid black',
}}
>
<div>
{headerGroups.map(headerGroup => (
<div {...headerGroup.getHeaderGroupProps()} className="header-group">
{headerGroup.headers.map(column => (
<div {...column.getHeaderProps()} className="header">
{column.render('Header')}
{column.canResize && (
<div
{...column.getResizerProps()}
className="resizer"
/>
)}
</div>
))}
</div>
))}
</div>
<div {...getTableBodyProps()}>
{rows.map(row => {
prepareRow(row);
return (
<div {...row.getRowProps()} className="row">
{row.cells.map(cell => (
<div {...cell.getCellProps()} className="cell">
{cell.render('Cell')}
</div>
))}
</div>
);
})}
</div>
<style jsx>{`
.header-group {
display: flex;
}
.header {
position: relative;
background: #f5f5f5;
border: 1px solid #ddd;
padding: 8px;
font-weight: bold;
}
.row {
display: flex;
}
.cell {
border: 1px solid #ddd;
padding: 8px;
overflow: hidden;
}
.resizer {
position: absolute;
right: 0;
top: 0;
height: 100%;
width: 5px;
background: rgba(0, 0, 0, 0.5);
cursor: col-resize;
user-select: none;
touch-action: none;
}
`}</style>
</div>
);
}Provides flexbox-based layout for responsive and flexible column sizing.
/**
* Adds flexbox layout to the table
* @param hooks - Hook registration object
*/
function useFlexLayout(hooks: Hooks): void;Usage Example:
import React from 'react';
import { useTable, useFlexLayout } from 'react-table';
function FlexLayoutTable({ columns, data }) {
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow,
} = useTable(
{
columns,
data,
},
useFlexLayout
);
return (
<div
{...getTableProps()}
style={{
display: 'flex',
flexDirection: 'column',
border: '1px solid black',
maxWidth: '100%',
}}
>
<div>
{headerGroups.map(headerGroup => (
<div
{...headerGroup.getHeaderGroupProps()}
style={{
display: 'flex',
backgroundColor: '#f5f5f5',
}}
>
{headerGroup.headers.map(column => (
<div
{...column.getHeaderProps()}
style={{
padding: '10px',
border: '1px solid #ddd',
fontWeight: 'bold',
flex: column.totalFlexWidth ? `${column.totalFlexWidth} 0 auto` : '1 1 auto',
}}
>
{column.render('Header')}
</div>
))}
</div>
))}
</div>
<div {...getTableBodyProps()}>
{rows.map(row => {
prepareRow(row);
return (
<div
{...row.getRowProps()}
style={{
display: 'flex',
}}
>
{row.cells.map(cell => (
<div
{...cell.getCellProps()}
style={{
padding: '10px',
border: '1px solid #ddd',
flex: cell.column.totalFlexWidth ? `${cell.column.totalFlexWidth} 0 auto` : '1 1 auto',
overflow: 'hidden',
}}
>
{cell.render('Cell')}
</div>
))}
</div>
);
})}
</div>
</div>
);
}Provides CSS Grid-based layout for advanced grid positioning and alignment.
/**
* Adds CSS Grid layout to the table
* @param hooks - Hook registration object
*/
function useGridLayout(hooks: Hooks): void;Usage Example:
import React from 'react';
import { useTable, useGridLayout } from 'react-table';
function GridLayoutTable({ columns, data }) {
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow,
} = useTable(
{
columns,
data,
},
useGridLayout
);
// Calculate grid template columns
const gridTemplateColumns = headerGroups[0]?.headers
.map(column => column.width || '1fr')
.join(' ') || 'repeat(auto-fit, minmax(150px, 1fr))';
return (
<div
{...getTableProps()}
style={{
display: 'grid',
gridTemplateColumns,
border: '1px solid black',
gap: '1px',
backgroundColor: '#ddd',
}}
>
{/* Headers */}
{headerGroups.map(headerGroup =>
headerGroup.headers.map(column => (
<div
key={column.id}
{...column.getHeaderProps()}
style={{
padding: '10px',
backgroundColor: '#f5f5f5',
fontWeight: 'bold',
display: 'flex',
alignItems: 'center',
}}
>
{column.render('Header')}
</div>
))
)}
{/* Body Cells */}
{rows.map(row => {
prepareRow(row);
return row.cells.map(cell => (
<div
key={`${row.id}-${cell.column.id}`}
{...cell.getCellProps()}
style={{
padding: '10px',
backgroundColor: 'white',
display: 'flex',
alignItems: 'center',
}}
>
{cell.render('Cell')}
</div>
));
})}
</div>
);
}When to use each layout:
| Layout | Use Case | Pros | Cons |
|---|---|---|---|
| Default | Simple tables, basic styling | Easy to style with CSS, familiar table markup | Less control over column sizing |
| Absolute | High-performance, virtualization | Best performance, precise positioning | Requires fixed dimensions |
| Block | Resizable columns, precise widths | Works well with resizing, precise control | More complex CSS |
| Flex | Responsive tables, flexible sizing | Responsive, flexible column distribution | Can be complex with many columns |
| Grid | Complex layouts, advanced alignment | Powerful grid features, clean markup | Browser support considerations |
Combine layout plugins with virtualization for handling large datasets.
import React from 'react';
import { FixedSizeList as List } from 'react-window';
import { useTable, useBlockLayout } from 'react-table';
function VirtualizedTable({ columns, data }) {
const defaultColumn = React.useMemo(
() => ({
width: 150,
}),
[]
);
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
totalColumnsWidth,
prepareRow,
} = useTable(
{
columns,
data,
defaultColumn,
},
useBlockLayout
);
const RenderRow = React.useCallback(
({ index, style }) => {
const row = rows[index];
prepareRow(row);
return (
<div
{...row.getRowProps({ style })}
className="row"
>
{row.cells.map(cell => (
<div {...cell.getCellProps()} className="cell">
{cell.render('Cell')}
</div>
))}
</div>
);
},
[prepareRow, rows]
);
return (
<div {...getTableProps()}>
<div>
{headerGroups.map(headerGroup => (
<div {...headerGroup.getHeaderGroupProps()} className="header-group">
{headerGroup.headers.map(column => (
<div {...column.getHeaderProps()} className="header">
{column.render('Header')}
</div>
))}
</div>
))}
</div>
<div {...getTableBodyProps()}>
<List
height={400}
itemCount={rows.length}
itemSize={35}
width={totalColumnsWidth}
>
{RenderRow}
</List>
</div>
</div>
);
}Create custom layout behaviors by implementing your own layout hook.
// Custom layout hook example
function useCustomLayout(hooks) {
hooks.getTableProps.push((props, { instance }) => [
props,
{
style: {
display: 'table',
borderCollapse: 'collapse',
width: '100%',
},
},
]);
hooks.getHeaderGroupProps.push((props) => [
props,
{
style: {
display: 'table-row',
},
},
]);
hooks.getHeaderProps.push((props, { column }) => [
props,
{
style: {
display: 'table-cell',
padding: '8px',
border: '1px solid #ccc',
backgroundColor: '#f5f5f5',
fontWeight: 'bold',
width: column.width,
},
},
]);
hooks.getRowProps.push((props) => [
props,
{
style: {
display: 'table-row',
},
},
]);
hooks.getCellProps.push((props, { cell }) => [
props,
{
style: {
display: 'table-cell',
padding: '8px',
border: '1px solid #ccc',
width: cell.column.width,
},
},
]);
}
// Use custom layout
function CustomLayoutTable({ columns, data }) {
const tableInstance = useTable(
{ columns, data },
useCustomLayout
);
// Table implementation...
}interface LayoutInstance {
/** Total width of all columns */
totalColumnsWidth?: number;
}
interface LayoutColumn {
/** Column width */
width?: number;
/** Minimum column width */
minWidth?: number;
/** Maximum column width */
maxWidth?: number;
/** Flex width for flex layout */
totalFlexWidth?: number;
}
interface LayoutMeta {
instance: TableInstance;
column?: Column;
row?: Row;
cell?: Cell;
}Install with Tessl CLI
npx tessl i tessl/npm-react-table