Sematable is a powerful, Redux-based table component library for React that provides comprehensive table functionality including sorting, filtering, pagination, and selection with a focus on server-side data management. It integrates seamlessly with Redux for state management, making it ideal for complex applications requiring centralized state control. This guide walks through creating feature-rich data tables using Sematable with React and Redux, covering setup, configuration, and practical implementation patterns. This is part 17 of a series on using Sematable with React.
Prerequisites
Before you begin, ensure you have:
- Node.js version 14.0 or higher
- npm, yarn, or pnpm package manager
- A React project (version 16.8 or higher) with hooks support
- Basic understanding of React hooks and Redux
- Redux and React-Redux installed (required dependencies)
- Familiarity with JavaScript/TypeScript
Installation
First, install Redux and React-Redux (required dependencies):
npm install redux react-redux
Then install Sematable:
npm install sematable
Or install everything with yarn:
yarn add redux react-redux sematable
Or with pnpm:
pnpm add redux react-redux sematable
Your package.json should include:
{
"dependencies": {
"sematable": "^3.0.0",
"redux": "^4.0.0",
"react-redux": "^8.0.0",
"react": "^18.0.0",
"react-dom": "^18.0.0"
}
}
Project Setup
Sematable requires Redux store setup. Configure your Redux store:
// src/store/index.js
import { createStore, combineReducers } from 'redux';
import { sematable } from 'sematable';
const rootReducer = combineReducers({
sematable: sematable,
// Add your other reducers here
});
const store = createStore(rootReducer);
export default store;
Update your main entry file to include the Redux Provider:
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import { Provider } from 'react-redux';
import store from './store';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>
);
First Example / Basic Usage
Let's create a basic table component. Create src/DataTable.jsx:
// src/DataTable.jsx
import React from 'react';
import { Sematable } from 'sematable';
import { tableConfig } from './tableConfig';
function DataTable() {
const data = [
{ 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' }
];
return (
<div style={{ padding: '20px' }}>
<h2>Employee Directory</h2>
<Sematable
config={tableConfig}
data={data}
/>
</div>
);
}
export default DataTable;
Create the table configuration file:
// src/tableConfig.js
import { makeTable } from 'sematable';
const tableConfig = makeTable('users', {
primaryKey: 'id',
columns: [
{
key: 'id',
label: 'ID',
sortable: true,
},
{
key: 'name',
label: 'Name',
sortable: true,
filterable: true,
},
{
key: 'email',
label: 'Email',
sortable: true,
filterable: true,
},
{
key: 'age',
label: 'Age',
sortable: true,
},
{
key: 'city',
label: 'City',
sortable: true,
filterable: true,
},
],
});
export { tableConfig };
Understanding the Basics
Sematable uses a Redux-based architecture where:
- makeTable: Creates a table configuration with a unique name
- primaryKey: Unique identifier for each row
- columns: Array of column definitions
- Sematable: Main component that renders the table
- Redux Store: Manages table state (sorting, filtering, pagination)
Key concepts:
- Table Name: Unique identifier for each table instance
- Columns: Define structure with key, label, sortable, filterable
- Redux Integration: Table state is managed in Redux store
- Server-side Support: Designed for server-side data loading
Here's an example with custom cell rendering:
// src/AdvancedTable.jsx
import React from 'react';
import { Sematable } from 'sematable';
import { makeTable } from 'sematable';
const productTableConfig = makeTable('products', {
primaryKey: 'id',
columns: [
{
key: 'id',
label: 'ID',
sortable: true,
},
{
key: 'name',
label: 'Product Name',
sortable: true,
filterable: true,
},
{
key: 'price',
label: 'Price',
sortable: true,
render: (value) => `$${value.toFixed(2)}`,
},
{
key: 'stock',
label: 'Stock',
sortable: true,
render: (value, row) => (
<span style={{
color: value < 10 ? 'red' : 'green',
fontWeight: 'bold'
}}>
{value}
</span>
),
},
{
key: 'status',
label: 'Status',
filterable: true,
render: (value) => (
<span style={{
padding: '4px 8px',
borderRadius: '4px',
backgroundColor: value === 'In Stock' ? '#d4edda' : '#fff3cd',
color: value === 'In Stock' ? '#155724' : '#856404'
}}>
{value}
</span>
),
},
],
});
function AdvancedTable() {
const data = [
{ id: 1, name: 'Laptop', price: 999.99, stock: 15, status: 'In Stock' },
{ id: 2, name: 'Mouse', price: 29.99, stock: 8, status: 'Low Stock' },
{ id: 3, name: 'Keyboard', price: 79.99, stock: 12, status: 'In Stock' }
];
return (
<div style={{ padding: '20px' }}>
<Sematable
config={productTableConfig}
data={data}
/>
</div>
);
}
export default AdvancedTable;
Practical Example / Building Something Real
Let's build a comprehensive employee management system with server-side data loading:
// src/EmployeeManagement.jsx
import React, { useState, useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { Sematable } from 'sematable';
import { makeTable } from 'sematable';
import { getTableState } from 'sematable';
const employeeTableConfig = makeTable('employees', {
primaryKey: 'id',
columns: [
{
key: 'id',
label: 'ID',
sortable: true,
width: 80,
},
{
key: 'name',
label: 'Employee Name',
sortable: true,
filterable: true,
render: (value, row) => (
<div>
<strong>{value}</strong>
<div style={{ fontSize: '12px', color: '#666' }}>
{row.email}
</div>
</div>
),
},
{
key: 'department',
label: 'Department',
sortable: true,
filterable: true,
render: (value) => {
const colors = {
Engineering: '#dc3545',
Marketing: '#ffc107',
Sales: '#28a745',
HR: '#17a2b8'
};
return (
<span style={{
padding: '4px 8px',
borderRadius: '4px',
backgroundColor: colors[value] || '#6c757d',
color: 'white',
fontSize: '12px'
}}>
{value}
</span>
);
},
},
{
key: 'salary',
label: 'Salary',
sortable: true,
render: (value) => `$${value.toLocaleString()}`,
},
{
key: 'startDate',
label: 'Start Date',
sortable: true,
render: (value) => {
const date = new Date(value);
return date.toLocaleDateString('en-US');
},
},
{
key: 'status',
label: 'Status',
sortable: true,
filterable: true,
render: (value) => (
<span style={{
padding: '4px 8px',
borderRadius: '4px',
backgroundColor: value === 'Active' ? '#d4edda' : '#f8d7da',
color: value === 'Active' ? '#155724' : '#721c24',
fontWeight: 'bold'
}}>
{value}
</span>
),
},
],
});
function EmployeeManagement() {
const dispatch = useDispatch();
const [data, setData] = useState([]);
const [loading, setLoading] = useState(false);
const tableState = useSelector(state =>
getTableState(state, 'employees')
);
useEffect(() => {
const fetchData = async () => {
setLoading(true);
try {
const params = new URLSearchParams({
page: (tableState?.page || 0).toString(),
pageSize: (tableState?.pageSize || 10).toString(),
sortBy: tableState?.sortBy || '',
sortDirection: tableState?.sortDirection || 'asc',
filter: tableState?.filter || '',
});
const response = await fetch(`/api/employees?${params}`);
const result = await response.json();
setData(result.data);
} catch (error) {
console.error('Error fetching data:', error);
} finally {
setLoading(false);
}
};
fetchData();
}, [tableState]);
return (
<div style={{ padding: '20px' }}>
<h2>Employee Management</h2>
{loading && <div>Loading...</div>}
<Sematable
config={employeeTableConfig}
data={data}
serverSide={true}
pageSize={10}
/>
</div>
);
}
export default EmployeeManagement;
This example demonstrates:
- Server-side data loading with Redux state management
- Custom cell rendering with React components
- Conditional styling based on data values
- Integration with Redux selectors
- Pagination, sorting, and filtering state management
- Loading states
Common Issues / Troubleshooting
Table not rendering: Ensure you've set up Redux store correctly and wrapped your app with Redux Provider. Verify that the sematable reducer is included in your store.
State not updating: Make sure you're using the correct table name in your configuration and when accessing state. Table names must match between config and selectors.
Server-side not working: For server-side mode, ensure you're listening to table state changes and fetching data accordingly. Use
getTableStateselector to access current table state.Filtering not working: Verify that
filterable: trueis set in column definitions. Check that your filter logic matches your data structure.Redux errors: Ensure Redux DevTools are properly configured if using them. Check that all actions are properly dispatched and reducers are correctly set up.
Next Steps
Now that you understand Sematable:
- Explore advanced Redux integration patterns
- Implement custom actions and reducers
- Add row selection and bulk operations
- Learn about server-side pagination and filtering
- Explore custom filter components
- Add export functionality
- Check the official repository: https://github.com/sematext/sematable
- Look for part 18 of this series for more advanced topics
Summary
You've learned how to set up Sematable and create feature-rich data tables with Redux integration, server-side data loading, and custom rendering. The library provides a robust foundation for building enterprise-grade data management interfaces with centralized state control through Redux.
SEO Keywords
sematable React
sematable Redux table
sematable tutorial
React Redux data table
sematable installation
React table with Redux
sematable example
React server-side table
sematable setup
React data grid Redux
sematable filtering
React table component
sematable pagination
React Redux table library
sematable getting started
Top comments (0)