React Table Library is a powerful, modular table component library for React that provides a flexible architecture for building complex data tables. It offers features like sorting, filtering, pagination, selection, and tree structures with a plugin-based system that allows extensive customization. This guide walks through implementing advanced table features using React Table Library with React, covering complex data manipulation, custom plugins, and enterprise-grade implementations. This is part 15 of a series on using React Table Library with React.
Prerequisites
Before you begin, ensure you have:
- Node.js version 16.0 or higher
- npm, yarn, or pnpm package manager
- A React project (version 16.8 or higher) with hooks support
- Advanced understanding of React hooks, context API, and state management
- Familiarity with TypeScript (highly recommended)
- Knowledge of functional programming and plugin architectures
Installation
Install React Table Library core package:
npm install @table-library/react-table-library
For additional features, install specific plugins:
npm install @table-library/react-table-library @table-library/react-table-library/theme @table-library/react-table-library/sort @table-library/react-table-library/filter @table-library/react-table-library/pagination
Or with yarn:
yarn add @table-library/react-table-library @table-library/react-table-library/theme @table-library/react-table-library/sort @table-library/react-table-library/filter @table-library/react-table-library/pagination
Your package.json should include:
{
"dependencies": {
"@table-library/react-table-library": "^4.0.0",
"react": "^18.0.0",
"react-dom": "^18.0.0"
}
}
Project Setup
React Table Library requires minimal setup. Import the necessary components and themes:
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
First Example / Basic Usage
Let's create a basic table component. Create src/DataTable.jsx:
// src/DataTable.jsx
import React, { useMemo } from 'react';
import {
Table,
Header,
HeaderRow,
HeaderCell,
Body,
Row,
Cell,
} from '@table-library/react-table-library/table';
import { useTheme } from '@table-library/react-table-library/theme';
import { DEFAULT_THEME } from '@table-library/react-table-library/theme';
function DataTable() {
const data = {
nodes: [
{ id: '1', name: 'John Doe', email: 'john@example.com', age: 28, city: 'New York' },
{ id: '2', name: 'Jane Smith', email: 'jane@example.com', age: 32, city: 'London' },
{ id: '3', name: 'Bob Johnson', email: 'bob@example.com', age: 45, city: 'Paris' },
{ id: '4', name: 'Alice Williams', email: 'alice@example.com', age: 29, city: 'Tokyo' }
]
};
const theme = useTheme(DEFAULT_THEME);
return (
<div style={{ padding: '20px' }}>
<h2>Employee Directory</h2>
<Table data={data} theme={theme}>
{(tableList) => (
<>
<Header>
<HeaderRow>
<HeaderCell>ID</HeaderRow>
<HeaderCell>Name</HeaderRow>
<HeaderCell>Email</HeaderRow>
<HeaderCell>Age</HeaderRow>
<HeaderCell>City</HeaderRow>
</HeaderRow>
</Header>
<Body>
{tableList.map((item) => (
<Row key={item.id} item={item}>
<Cell>{item.id}</Cell>
<Cell>{item.name}</Cell>
<Cell>{item.email}</Cell>
<Cell>{item.age}</Cell>
<Cell>{item.city}</Cell>
</Row>
))}
</Body>
</>
)}
</Table>
</div>
);
}
export default DataTable;
Understanding the Basics
React Table Library uses a plugin-based architecture where:
- Table: Main component that wraps the table structure
-
Data Structure: Uses
{ nodes: [...] }format - Render Props: Table uses render props pattern for rendering
- Plugins: Enable features like sorting, filtering, pagination
- Theme: Customizable theming system
Key concepts for advanced usage:
-
Nodes: Data items in the
nodesarray - Plugins: Modular features (sort, filter, pagination, etc.)
- Theme: Styling system with built-in themes or custom themes
- Render Props: Table component uses render props for flexible rendering
Here's an example with sorting:
// src/SortableTable.jsx
import React, { useMemo } from 'react';
import {
Table,
Header,
HeaderRow,
HeaderCell,
Body,
Row,
Cell,
} from '@table-library/react-table-library/table';
import { useSort } from '@table-library/react-table-library/sort';
import { useTheme } from '@table-library/react-table-library/theme';
import { DEFAULT_THEME } from '@table-library/react-table-library/theme';
function SortableTable() {
const data = {
nodes: [
{ id: '1', name: 'Laptop', category: 'Electronics', price: 999.99, stock: 15 },
{ id: '2', name: 'Mouse', category: 'Electronics', price: 29.99, stock: 8 },
{ id: '3', name: 'Keyboard', category: 'Electronics', price: 79.99, stock: 12 }
]
};
const theme = useTheme(DEFAULT_THEME);
const sort = useSort(
data,
{
onChange: onSortChange,
},
{
sortFns: {
PRICE: (array) => array.sort((a, b) => a.price - b.price),
STOCK: (array) => array.sort((a, b) => a.stock - b.stock),
},
}
);
function onSortChange(action, state) {
console.log(action, state);
}
return (
<Table data={data} theme={theme} sort={sort}>
{(tableList) => (
<>
<Header>
<HeaderRow>
<HeaderCell sort={{ sortKey: 'NAME' }}>Name</HeaderRow>
<HeaderCell sort={{ sortKey: 'CATEGORY' }}>Category</HeaderRow>
<HeaderCell sort={{ sortKey: 'PRICE' }}>Price</HeaderRow>
<HeaderCell sort={{ sortKey: 'STOCK' }}>Stock</HeaderRow>
</HeaderRow>
</Header>
<Body>
{tableList.map((item) => (
<Row key={item.id} item={item}>
<Cell>{item.name}</Cell>
<Cell>{item.category}</Cell>
<Cell>${item.price.toFixed(2)}</Cell>
<Cell>{item.stock}</Cell>
</Row>
))}
</Body>
</>
)}
</Table>
);
}
export default SortableTable;
Practical Example / Building Something Real
Let's build a comprehensive admin dashboard with sorting, filtering, pagination, and selection:
// src/AdminDashboard.jsx
import React, { useState, useMemo } from 'react';
import {
Table,
Header,
HeaderRow,
HeaderCell,
Body,
Row,
Cell,
} from '@table-library/react-table-library/table';
import { useSort } from '@table-library/react-table-library/sort';
import { useFilter } from '@table-library/react-table-library/filter';
import { usePagination } from '@table-library/react-table-library/pagination';
import { useRowSelect } from '@table-library/react-table-library/select';
import { useTheme } from '@table-library/react-table-library/theme';
import { DEFAULT_THEME } from '@table-library/react-table-library/theme';
function AdminDashboard() {
const [data, setData] = useState({
nodes: [
{
id: '1',
name: 'Sarah Johnson',
email: 'sarah@example.com',
department: 'Engineering',
salary: 95000,
startDate: '2020-01-15',
status: 'Active'
},
{
id: '2',
name: 'Michael Chen',
email: 'michael@example.com',
department: 'Marketing',
salary: 75000,
startDate: '2019-06-20',
status: 'Active'
},
{
id: '3',
name: 'Emily Davis',
email: 'emily@example.com',
department: 'Sales',
salary: 65000,
startDate: '2021-03-10',
status: 'Active'
},
{
id: '4',
name: 'David Wilson',
email: 'david@example.com',
department: 'Engineering',
salary: 110000,
startDate: '2018-09-05',
status: 'Active'
},
{
id: '5',
name: 'Lisa Anderson',
email: 'lisa@example.com',
department: 'HR',
salary: 70000,
startDate: '2022-01-08',
status: 'Active'
}
]
});
const theme = useTheme(DEFAULT_THEME);
// Sorting
const sort = useSort(
data,
{
onChange: onSortChange,
},
{
sortFns: {
SALARY: (array) => array.sort((a, b) => a.salary - b.salary),
START_DATE: (array) => array.sort((a, b) =>
new Date(a.startDate) - new Date(b.startDate)
),
},
}
);
// Filtering
const filter = useFilter(
data,
{
onChange: onFilterChange,
},
{
isServerSide: false,
}
);
// Pagination
const pagination = usePagination(data, {
state: {
page: 0,
size: 10,
},
onChange: onPaginationChange,
});
// Row Selection
const select = useRowSelect(data, {
onChange: onSelectChange,
});
function onSortChange(action, state) {
console.log('Sort changed:', state);
}
function onFilterChange(action, state) {
console.log('Filter changed:', state);
}
function onPaginationChange(action, state) {
console.log('Pagination changed:', state);
}
function onSelectChange(action, state) {
console.log('Selection changed:', state);
}
const handleSearch = (value) => {
filter.fns.onFilterChange({
type: 'FILTER',
payload: {
name: value,
},
});
};
return (
<div style={{ padding: '20px' }}>
<h2>Admin Dashboard</h2>
{/* Search */}
<div style={{ marginBottom: '16px' }}>
<input
type="text"
placeholder="Search employees..."
onChange={(e) => handleSearch(e.target.value)}
style={{
padding: '8px',
width: '300px',
border: '1px solid #ddd',
borderRadius: '4px'
}}
/>
</div>
{/* Table */}
<Table
data={data}
theme={theme}
sort={sort}
filter={filter}
pagination={pagination}
select={select}
>
{(tableList) => (
<>
<Header>
<HeaderRow>
<HeaderCell>
<input
type="checkbox"
checked={select.state.all}
onChange={select.fns.onToggleAll}
/>
</HeaderRow>
<HeaderCell sort={{ sortKey: 'NAME' }}>Name</HeaderRow>
<HeaderCell sort={{ sortKey: 'EMAIL' }}>Email</HeaderRow>
<HeaderCell sort={{ sortKey: 'DEPARTMENT' }}>Department</HeaderRow>
<HeaderCell sort={{ sortKey: 'SALARY' }}>Salary</HeaderRow>
<HeaderCell sort={{ sortKey: 'START_DATE' }}>Start Date</HeaderRow>
<HeaderCell sort={{ sortKey: 'STATUS' }}>Status</HeaderRow>
</HeaderRow>
</Header>
<Body>
{tableList.map((item) => (
<Row
key={item.id}
item={item}
style={{
backgroundColor: select.state.ids.includes(item.id)
? '#e3f2fd'
: 'white'
}}
>
<Cell>
<input
type="checkbox"
checked={select.state.ids.includes(item.id)}
onChange={() => select.fns.onToggleById(item.id)}
/>
</Cell>
<Cell>
<div>
<strong>{item.name}</strong>
<div style={{ fontSize: '12px', color: '#666' }}>
{item.email}
</div>
</div>
</Cell>
<Cell>{item.email}</Cell>
<Cell>
<span style={{
padding: '4px 8px',
borderRadius: '4px',
backgroundColor: '#dc3545',
color: 'white',
fontSize: '12px'
}}>
{item.department}
</span>
</Cell>
<Cell>${item.salary.toLocaleString()}</Cell>
<Cell>
{new Date(item.startDate).toLocaleDateString('en-US')}
</Cell>
<Cell>
<span style={{
padding: '4px 8px',
borderRadius: '4px',
backgroundColor: item.status === 'Active' ? '#d4edda' : '#f8d7da',
color: item.status === 'Active' ? '#155724' : '#721c24',
fontWeight: 'bold'
}}>
{item.status}
</span>
</Cell>
</Row>
))}
</Body>
</>
)}
</Table>
{/* Pagination Controls */}
<div style={{ marginTop: '16px', display: 'flex', gap: '8px', alignItems: 'center' }}>
<button
onClick={() => pagination.fns.onSetPage(0)}
disabled={pagination.state.page === 0}
style={{ padding: '8px 16px', cursor: 'pointer' }}
>
{'<<'}
</button>
<button
onClick={() => pagination.fns.onSetPage(pagination.state.page - 1)}
disabled={pagination.state.page === 0}
style={{ padding: '8px 16px', cursor: 'pointer' }}
>
{'<'}
</button>
<span>
Page {pagination.state.page + 1} of {pagination.state.getTotalPages(data.nodes)}
</span>
<button
onClick={() => pagination.fns.onSetPage(pagination.state.page + 1)}
disabled={pagination.state.page + 1 >= pagination.state.getTotalPages(data.nodes)}
style={{ padding: '8px 16px', cursor: 'pointer' }}
>
{'>'}
</button>
<button
onClick={() => pagination.fns.onSetPage(pagination.state.getTotalPages(data.nodes) - 1)}
disabled={pagination.state.page + 1 >= pagination.state.getTotalPages(data.nodes)}
style={{ padding: '8px 16px', cursor: 'pointer' }}
>
{'>>'}
</button>
</div>
</div>
);
}
export default AdminDashboard;
This advanced example demonstrates:
- Multiple plugins working together (sort, filter, pagination, select)
- Custom cell rendering with React components
- Row selection with checkboxes
- Global search/filtering
- Custom sorting functions
- Pagination controls
- Conditional styling
- Status badges and department chips
Common Issues / Troubleshooting
Table not rendering: Ensure your data structure uses
{ nodes: [...] }format. The Table component expects this specific structure.Plugins not working: Make sure you've installed the specific plugin packages and imported them correctly. Each plugin needs to be passed to the Table component.
Sorting not working: Verify that you've included the
sortprop fromuseSorthook and setsortKeyin HeaderCell components.Filtering issues: Ensure you've set up the filter plugin correctly and are calling filter functions properly. Check that your filter logic matches your data structure.
TypeScript errors: React Table Library has TypeScript support. Define your data types and ensure your node structure matches the expected interface.
Next Steps
Now that you've mastered React Table Library:
- Explore tree table features for hierarchical data
- Implement custom plugins and extensions
- Add server-side data loading
- Learn about column resizing and reordering
- Explore advanced theming and customization
- Add export functionality
- Check the official repository: https://github.com/table-library/react-table-library
- Look for part 16 of this series for more advanced topics
Summary
You've learned how to implement advanced data table features with React Table Library, including sorting, filtering, pagination, and row selection using a plugin-based architecture. The library provides extensive flexibility for building enterprise-grade data management interfaces with modular, composable features.
SEO Keywords
react-table-library
React Table Library tutorial
react-table-library advanced
React data table plugin
react-table-library installation
React table component
react-table-library example
React data grid
react-table-library setup
React interactive table
react-table-library sorting
React enterprise table
react-table-library filtering
React table library pagination
react-table-library selection
Top comments (0)