1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
# ClientVirtualTable V3 Guide
This version introduces the `useClientTable` hook to drastically reduce boilerplate code and improve Developer Experience (DX).
## Key Changes from V2
- **`useClientTable` Hook**: Manages all state (sorting, filtering, pagination, grouping) and data fetching (Client or Server).
- **Cleaner Component**: `ClientVirtualTable` now accepts a `table` instance prop, making it a pure renderer.
- **Better Separation**: Logic is in the hook; UI is in the component.
## Usage
### 1. Client-Side Mode
Load all data once, let the hook handle the rest.
```tsx
import { useClientTable, ClientVirtualTable } from "@/components/client-table-v3";
function MyTable() {
const [data, setData] = useState([]);
// Load data...
const { table, isLoading } = useClientTable({
fetchMode: "client",
data,
columns,
enablePagination: true, // Auto-enabled
});
return <ClientVirtualTable table={table} isLoading={isLoading} />;
}
```
### 2. Server-Side Mode (Factory Service)
Pass your server action as the `fetcher`. The hook handles debouncing and refetching.
```tsx
import { useClientTable, ClientVirtualTable } from "@/components/client-table-v3";
import { myServerAction } from "./actions";
function MyServerTable() {
const { table, isLoading } = useClientTable({
fetchMode: "server",
fetcher: myServerAction, // Must accept TableState
columns,
enablePagination: true,
});
return <ClientVirtualTable table={table} isLoading={isLoading} />;
}
```
### 3. Server Grouping (Pattern 2-B)
The hook detects server-side grouping responses and provides them separately.
```tsx
const { table, isLoading, isServerGrouped, serverGroups } = useClientTable({
fetchMode: "server",
fetcher: myGroupFetcher,
columns,
enableGrouping: true,
});
if (isServerGrouped) {
return <MyGroupRenderer groups={serverGroups} />;
}
return <ClientVirtualTable table={table} ... />;
```
## Hook Options (`useClientTable`)
| Option | Type | Description |
|--------|------|-------------|
| `fetchMode` | `'client' \| 'server'` | Default `'client'`. |
| `data` | `TData[]` | Data for client mode. |
| `fetcher` | `(state) => Promise` | Server action for server mode. |
| `columns` | `ColumnDef[]` | Column definitions. |
| `initialState` | `object` | Initial sorting, filters, etc. |
| `enablePagination` | `boolean` | Enable pagination logic. |
| `enableGrouping` | `boolean` | Enable grouping logic. |
## Component Props (`ClientVirtualTable`)
| Prop | Type | Description |
|------|------|-------------|
| `table` | `Table<TData>` | The table instance from the hook. |
| `isLoading` | `boolean` | Shows loading overlay. |
| `height` | `string` | Table height (required for virtualization). |
| `enableUserPreset` | `boolean` | Enable saving/loading view presets. |
| `tableKey` | `string` | Unique key for presets. |
## Migration from V2
1. Replace `<ClientVirtualTable ...props />` with `const { table } = useClientTable({...}); <ClientVirtualTable table={table} />`.
2. Remove local state (`sorting`, `pagination`, `useEffect` for fetching) from your page component.
3. Pass `fetcher` directly to the hook.
|