GigaTables React is a powerful, feature-rich table component library for React that provides advanced data management capabilities including server-side processing, real-time updates, complex filtering, and custom rendering. It's designed for enterprise applications that require sophisticated data manipulation and presentation. This guide walks through implementing advanced table features using GigaTables React, covering server-side data loading, custom components, and complex interactions. This is part 3 of a series on using GigaTables React 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 async operations and API integration
- Knowledge of TypeScript (optional but recommended)
Installation
Install GigaTables React and its dependencies:
npm install gigatables-react
Or with yarn:
yarn add gigatables-react
Or with pnpm:
pnpm add gigatables-react
For TypeScript support, you may also need type definitions:
npm install --save-dev @types/react @types/react-dom
Your package.json should include:
{
"dependencies": {
"gigatables-react": "^3.0.0",
"react": "^18.0.0",
"react-dom": "^18.0.0"
},
"devDependencies": {
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0"
}
}
Project Setup
GigaTables React requires minimal setup. Create a configuration file for table settings:
// src/config/tableConfig.js
export const defaultTableConfig = {
ajax: {
url: '/api/data',
type: 'GET'
},
columns: [],
pagination: {
enabled: true,
pageSize: 10,
position: 'bottom'
},
sorting: {
enabled: true,
multiColumn: true
},
filtering: {
enabled: true,
global: true
}
};
First Example / Basic Usage
Let's create a basic table component. Create src/components/DataTable.jsx:
// src/components/DataTable.jsx
import React, { useState, useEffect } from 'react';
import { GigaTables } from 'gigatables-react';
function DataTable() {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
// Simulate API call
const fetchData = async () => {
try {
setLoading(true);
const response = await fetch('/api/users');
const result = await response.json();
setData(result);
} catch (error) {
console.error('Error fetching data:', error);
} finally {
setLoading(false);
}
};
fetchData();
}, []);
const columns = [
{
name: 'id',
title: 'ID',
sortable: true,
width: 80
},
{
name: 'name',
title: 'Name',
sortable: true,
filterable: true
},
{
name: 'email',
title: 'Email',
sortable: true,
filterable: true
},
{
name: 'role',
title: 'Role',
sortable: true,
filterable: true
},
{
name: 'status',
title: 'Status',
sortable: true,
render: (value) => (
<span style={{
color: value === 'active' ? 'green' : 'red',
fontWeight: 'bold'
}}>
{value}
</span>
)
}
];
if (loading) {
return <div>Loading...</div>;
}
return (
<div style={{ padding: '20px' }}>
<h2>User Management Table</h2>
<GigaTables
data={data}
columns={columns}
pagination={{
enabled: true,
pageSize: 10
}}
sorting={{
enabled: true
}}
filtering={{
enabled: true
}}
/>
</div>
);
}
export default DataTable;
Understanding the Basics
GigaTables React uses a column-based configuration system where each column defines:
- name: Property key in your data objects
- title: Display header text
- sortable: Enable sorting for the column
- filterable: Enable filtering
- render: Custom render function for cell content
- width: Fixed column width
Key concepts for advanced usage:
- Server-side processing: Load data asynchronously from APIs
- Custom renderers: Create complex cell content with React components
- Event handlers: Respond to user interactions (sort, filter, paginate)
- State management: Integrate with Redux, Context API, or local state
Here's an example with server-side data loading:
// src/components/ServerSideTable.jsx
import React, { useState, useCallback } from 'react';
import { GigaTables } from 'gigatables-react';
function ServerSideTable() {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(false);
const [pagination, setPagination] = useState({
page: 1,
pageSize: 10,
total: 0
});
const [filters, setFilters] = useState({});
const [sorting, setSorting] = useState({});
const fetchData = useCallback(async () => {
setLoading(true);
try {
const params = new URLSearchParams({
page: pagination.page.toString(),
pageSize: pagination.pageSize.toString(),
...filters,
...sorting
});
const response = await fetch(`/api/data?${params}`);
const result = await response.json();
setData(result.data);
setPagination(prev => ({
...prev,
total: result.total
}));
} catch (error) {
console.error('Error:', error);
} finally {
setLoading(false);
}
}, [pagination.page, pagination.pageSize, filters, sorting]);
React.useEffect(() => {
fetchData();
}, [fetchData]);
const handlePageChange = (page) => {
setPagination(prev => ({ ...prev, page }));
};
const handleSort = (column, direction) => {
setSorting({ [column]: direction });
};
const handleFilter = (column, value) => {
setFilters(prev => ({
...prev,
[column]: value
}));
};
const columns = [
{ name: 'id', title: 'ID', sortable: true },
{ name: 'name', title: 'Name', sortable: true, filterable: true },
{ name: 'email', title: 'Email', sortable: true, filterable: true },
{ name: 'created', title: 'Created', sortable: true }
];
return (
<GigaTables
data={data}
columns={columns}
loading={loading}
pagination={{
enabled: true,
page: pagination.page,
pageSize: pagination.pageSize,
total: pagination.total,
onPageChange: handlePageChange
}}
sorting={{
enabled: true,
onSort: handleSort
}}
filtering={{
enabled: true,
onFilter: handleFilter
}}
/>
);
}
export default ServerSideTable;
Practical Example / Building Something Real
Let's build a comprehensive admin dashboard table with advanced features:
// src/components/AdminDashboardTable.jsx
import React, { useState, useEffect, useCallback } from 'react';
import { GigaTables } from 'gigatables-react';
function AdminDashboardTable() {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(false);
const [selectedRows, setSelectedRows] = useState([]);
const [pagination, setPagination] = useState({
page: 1,
pageSize: 20,
total: 0
});
const [filters, setFilters] = useState({});
const [sorting, setSorting] = useState({ column: 'id', direction: 'asc' });
const fetchData = useCallback(async () => {
setLoading(true);
try {
const queryParams = new URLSearchParams({
page: pagination.page.toString(),
limit: pagination.pageSize.toString(),
sortBy: sorting.column,
sortOrder: sorting.direction,
...Object.entries(filters).reduce((acc, [key, value]) => {
if (value) acc[key] = value;
return acc;
}, {})
});
const response = await fetch(`/api/admin/users?${queryParams}`);
const result = await response.json();
setData(result.users);
setPagination(prev => ({
...prev,
total: result.total
}));
} catch (error) {
console.error('Failed to fetch data:', error);
} finally {
setLoading(false);
}
}, [pagination.page, pagination.pageSize, filters, sorting]);
useEffect(() => {
fetchData();
}, [fetchData]);
const handleBulkAction = async (action) => {
if (selectedRows.length === 0) return;
try {
const response = await fetch('/api/admin/users/bulk', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
action,
ids: selectedRows
})
});
if (response.ok) {
setSelectedRows([]);
fetchData();
}
} catch (error) {
console.error('Bulk action failed:', error);
}
};
const columns = [
{
name: 'id',
title: 'ID',
width: 80,
sortable: true,
render: (value, row) => (
<input
type="checkbox"
checked={selectedRows.includes(row.id)}
onChange={(e) => {
if (e.target.checked) {
setSelectedRows([...selectedRows, row.id]);
} else {
setSelectedRows(selectedRows.filter(id => id !== row.id));
}
}}
/>
)
},
{
name: 'avatar',
title: 'Avatar',
width: 80,
render: (value) => (
<img
src={value || '/default-avatar.png'}
alt="Avatar"
style={{
width: '40px',
height: '40px',
borderRadius: '50%',
objectFit: 'cover'
}}
/>
)
},
{
name: 'name',
title: 'Full Name',
sortable: true,
filterable: true,
render: (value, row) => (
<div>
<strong>{value}</strong>
<div style={{ fontSize: '12px', color: '#666' }}>
{row.email}
</div>
</div>
)
},
{
name: 'role',
title: 'Role',
sortable: true,
filterable: true,
render: (value) => {
const colors = {
admin: '#dc3545',
manager: '#ffc107',
user: '#28a745'
};
return (
<span
style={{
padding: '4px 8px',
borderRadius: '4px',
backgroundColor: colors[value] || '#6c757d',
color: 'white',
fontSize: '12px',
fontWeight: 'bold'
}}
>
{value.toUpperCase()}
</span>
);
}
},
{
name: 'status',
title: 'Status',
sortable: true,
filterable: true,
render: (value) => (
<span
style={{
display: 'inline-block',
width: '10px',
height: '10px',
borderRadius: '50%',
backgroundColor: value === 'active' ? '#28a745' : '#dc3545',
marginRight: '8px'
}}
/>
)
},
{
name: 'lastLogin',
title: 'Last Login',
sortable: true,
render: (value) => {
if (!value) return 'Never';
const date = new Date(value);
return date.toLocaleDateString('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit'
});
}
},
{
name: 'actions',
title: 'Actions',
width: 150,
render: (value, row) => (
<div>
<button
onClick={() => handleEdit(row.id)}
style={{
marginRight: '8px',
padding: '4px 8px',
border: '1px solid #007bff',
backgroundColor: 'white',
color: '#007bff',
borderRadius: '4px',
cursor: 'pointer'
}}
>
Edit
</button>
<button
onClick={() => handleDelete(row.id)}
style={{
padding: '4px 8px',
border: '1px solid #dc3545',
backgroundColor: 'white',
color: '#dc3545',
borderRadius: '4px',
cursor: 'pointer'
}}
>
Delete
</button>
</div>
)
}
];
const handleEdit = (id) => {
console.log('Edit user:', id);
// Implement edit logic
};
const handleDelete = async (id) => {
if (window.confirm('Are you sure you want to delete this user?')) {
try {
await fetch(`/api/admin/users/${id}`, { method: 'DELETE' });
fetchData();
} catch (error) {
console.error('Delete failed:', error);
}
}
};
return (
<div style={{ padding: '20px' }}>
<div style={{ marginBottom: '20px', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<h2>Admin Dashboard</h2>
<div>
{selectedRows.length > 0 && (
<>
<button
onClick={() => handleBulkAction('activate')}
style={{ marginRight: '8px', padding: '8px 16px' }}
>
Activate Selected ({selectedRows.length})
</button>
<button
onClick={() => handleBulkAction('deactivate')}
style={{ marginRight: '8px', padding: '8px 16px' }}
>
Deactivate Selected
</button>
<button
onClick={() => handleBulkAction('delete')}
style={{ padding: '8px 16px', backgroundColor: '#dc3545', color: 'white', border: 'none' }}
>
Delete Selected
</button>
</>
)}
</div>
</div>
<GigaTables
data={data}
columns={columns}
loading={loading}
pagination={{
enabled: true,
page: pagination.page,
pageSize: pagination.pageSize,
total: pagination.total,
onPageChange: (page) => setPagination(prev => ({ ...prev, page }))
}}
sorting={{
enabled: true,
column: sorting.column,
direction: sorting.direction,
onSort: (column, direction) => setSorting({ column, direction })
}}
filtering={{
enabled: true,
filters: filters,
onFilter: (column, value) => {
setFilters(prev => ({
...prev,
[column]: value
}));
setPagination(prev => ({ ...prev, page: 1 }));
}}
}}
/>
</div>
);
}
export default AdminDashboardTable;
This advanced example demonstrates:
- Server-side data loading with pagination, sorting, and filtering
- Custom cell renderers with complex components
- Row selection and bulk actions
- Real-time data updates
- Custom action buttons per row
- Loading states and error handling
- Responsive design considerations
Common Issues / Troubleshooting
Data not loading: Ensure your API endpoints return data in the expected format. Check network requests in browser DevTools and verify CORS settings if calling external APIs.
Sorting/filtering not working: Verify that your column definitions have
sortable: trueorfilterable: trueset, and that your data handler functions are properly connected to the table events.Performance issues with large datasets: Implement server-side processing instead of loading all data at once. Use pagination and lazy loading for better performance.
Custom renderers not updating: Make sure your render functions are pure and don't depend on external state that might not trigger re-renders. Use React.memo for expensive render functions.
TypeScript errors: Install proper type definitions and ensure your column definitions match the expected interface structure.
Next Steps
Now that you've mastered advanced GigaTables React features:
- Explore custom plugins and extensions
- Implement real-time data synchronization with WebSockets
- Add advanced filtering with multiple conditions
- Create custom export functionality (CSV, Excel, PDF)
- Integrate with state management libraries (Redux, Zustand)
- Build reusable table components and hooks
- Check the official repository: https://github.com/GigaTables/reactables
- Look for part 4 of this series for more advanced topics
Summary
You've learned how to implement advanced data management features with GigaTables React, including server-side processing, custom rendering, bulk operations, and complex interactions. The library provides a robust foundation for building enterprise-grade data tables with sophisticated functionality and excellent performance.
Top comments (0)