Skip to content

Commit 9dde1cd

Browse files
authoredMar 5, 2024··
docs: create react state guide and reorg sidebar guides (#5389)
1 parent 7789066 commit 9dde1cd

File tree

3 files changed

+222
-4
lines changed

3 files changed

+222
-4
lines changed
 

‎docs/config.json

+17-3
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,14 @@
3232
]
3333
},
3434
{
35-
"label": "Guides",
35+
"label": "Core Guides",
3636
"children": [
3737
{
3838
"label": "Migrating to V8",
3939
"to": "guide/migrating"
4040
},
4141
{
42-
"label": "Tables (Getting Started)",
42+
"label": "Table Instance",
4343
"to": "guide/tables"
4444
},
4545
{
@@ -61,7 +61,12 @@
6161
{
6262
"label": "Cells",
6363
"to": "guide/cells"
64-
},
64+
}
65+
]
66+
},
67+
{
68+
"label": "Feature Guides",
69+
"children": [
6570
{
6671
"label": "Features",
6772
"to": "guide/features"
@@ -229,6 +234,15 @@
229234
}
230235
]
231236
},
237+
{
238+
"label": "Core Guides",
239+
"children": [
240+
{
241+
"label": "Table State (React)",
242+
"to": "framework/react/guide/table-state"
243+
}
244+
]
245+
},
232246
{
233247
"label": "Examples",
234248
"children": [
+204
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
---
2+
title: Table State (React) Guide
3+
---
4+
5+
## Examples
6+
7+
Want to skip to the implementation? Check out these examples:
8+
9+
- [kitchen sink](../examples/kitchen-sink)
10+
- [fully controlled](../examples/fully-controlled)
11+
12+
## Table State (React) Guide
13+
14+
TanStack Table has a simple underlying internal state management system to store and manage the state of the table. It also lets you selectively pull out any state that you need to manage in your own state management. This guide will walk you through the different ways in which you can interact with and manage the state of the table.
15+
16+
### Accessing Table State
17+
18+
You do not need to set up anything special in order for the table state to work. If you pass noting into either `state`, `initialState`, or any of the `on[State]Change` table options, the table will manage its own state internally. You can access any part of this internal state by using the `table.getState()` table instance API.
19+
20+
```jsx
21+
const table = useReactTable({
22+
columns,
23+
data,
24+
//...
25+
})
26+
27+
console.log(table.getState()) //access the entire internal state
28+
console.log(table.getState().rowSelection) //access just the row selection state
29+
```
30+
31+
### Custom Initial State
32+
33+
If all you need to do for certain states is customize their initial default values, you still do not need to manage any of the state yourself. You can simply set values in the `initialState` option of the table instance.
34+
35+
```jsx
36+
const table = useReactTable({
37+
columns,
38+
data,
39+
initialState: {
40+
columnOrder: ['age', 'firstName', 'lastName'], //customize the initial column order
41+
columnVisibility: {
42+
id: false //hide the id column by default
43+
},
44+
expanded: true, //expand all rows by default
45+
sorting: [
46+
{
47+
id: 'age',
48+
desc: true //sort by age in descending order by default
49+
}
50+
]
51+
},
52+
//...
53+
})
54+
```
55+
56+
> **Note**: Only specify each particular state in either `initialState` or `state`, but not both. If you pass in a particular state value to both `initialState` and `state`, the initialized state in `state` will take overwrite any corresponding value in `initialState`.
57+
58+
### Controlled State
59+
60+
If you need easy access to the table state in other areas of your application, TanStack Table makes it easy to control and manage any or all of the table state in your own state management system. You can do this by passing in your own state and state management functions to the `state` and `on[State]Change` table options.
61+
62+
#### Individual Controlled State
63+
64+
You can control just the state that you need easy access to. You do NOT have to control all of the table state if you do not need to. It is recommended to only control the state that you need on a case-by-case basis.
65+
66+
In order to control a particular state, you need to both pass in the corresponding `state` value and the `on[State]Change` function to the table instance.
67+
68+
Let's take filtering, sorting, and pagination as an example in a "manual" server-side data fetching scenario. You can store the filtering, sorting, and pagination state in your own state management, but leave out any other state like column order, column visibility, etc. if your API does not care about those values.
69+
70+
```jsx
71+
const [columnFilters, setColumnFilters] = React.useState([]) //no default filters
72+
const [sorting, setSorting] = React.useState([{
73+
id: 'age',
74+
desc: true, //sort by age in descending order by default
75+
}])
76+
const [pagination, setPagination] = React.useState({ pageIndex: 0, pageSize: 15 })
77+
78+
//Use our controlled state values to fetch data
79+
const tableQuery = useQuery({
80+
queryKey: ['users', columnFilters, sorting, pagination],
81+
queryFn: () => fetchUsers(columnFilters, sorting, pagination),
82+
//...
83+
})
84+
85+
const table = useReactTable({
86+
columns,
87+
data: tableQuery.data,
88+
//...
89+
state: {
90+
columnFilters, //pass controlled state back to the table (overrides internal state)
91+
sorting,
92+
pagination
93+
},
94+
onColumnFiltersChange: setColumnFilters, //hoist columnFilters state into our own state management
95+
onSortingChange: setSorting,
96+
onPaginationChange: setPagination,
97+
})
98+
//...
99+
```
100+
101+
#### Fully Controlled State
102+
103+
Alternatively, you can control the entire table state with the `onStateChange` table option. It will hoist out the entire table state into your own state management system. Be careful with this approach, as you might find that raising some frequently changing state values up a react tree, like `columnSizingInfo` state`, might cause bad performance issues.
104+
105+
A couple of more tricks may be needed to make this work. If you use the `onStateChange` table option, the initial values of the `state` must be populated with all of the relevant state values for all of the features that you want to use. You can either manually type out all of the initial state values, or use the `table.setOptions` API in a special way as shown below.
106+
107+
```jsx
108+
//create a table instance with default state values
109+
const table = useReactTable({
110+
columns,
111+
data,
112+
//... Note: `state` values are NOT passed in yet
113+
})
114+
115+
116+
const [state, setState] = React.useState({
117+
...table.initialState, //populate the initial state with all of the default state values from the table instance
118+
pagination: {
119+
pageIndex: 0,
120+
pageSize: 15 //optionally customize the initial pagination state.
121+
}
122+
})
123+
124+
//Use the table.setOptions API to merge our fully controlled state onto the table instance
125+
table.setOptions(prev => ({
126+
...prev, //preserve any other options that we have set up above
127+
state, //our fully controlled state overrides the internal state
128+
onStateChange: setState //any state changes will be pushed up to our own state management
129+
}))
130+
```
131+
132+
### On State Change Callbacks
133+
134+
So far, we have seen the `on[State]Change` and `onStateChange` table options work to "hoist" the table state changes into our own state management. However, there are a few things about these using these options that you should be aware of.
135+
136+
#### 1. **State Change Callbacks MUST have their corresponding state value in the `state` option**.
137+
138+
Specifying an `on[State]Change` callback tells the table instance that this will be a controlled state. If you do not specify the corresponding `state` value, that state will be "frozen" with its initial value.
139+
140+
```jsx
141+
const [sorting, setSorting] = React.useState([])
142+
//...
143+
const table = useReactTable({
144+
columns,
145+
data,
146+
//...
147+
state: {
148+
sorting, //required because we are using `onSortingChange`
149+
},
150+
onSortingChange: setSorting, //makes the `state.sorting` controlled
151+
})
152+
```
153+
154+
#### 2. **Updaters can either be raw values or callback functions**.
155+
156+
The `on[State]Change` and `onStateChange` callbacks work exactly like the `setState` functions in React. The updater values can either be a new state value or a callback function that takes the previous state value and returns the new state value.
157+
158+
What implications does this have? It means that if you want to add in some extra logic in any of the `on[State]Change` callbacks, you can do so, but you need to check whether or not the new incoming updater value is a function or value.
159+
160+
```jsx
161+
const [sorting, setSorting] = React.useState([])
162+
const [pagination, setPagination] = React.useState({ pageIndex: 0, pageSize: 10 })
163+
164+
const table = useReactTable({
165+
columns,
166+
data,
167+
//...
168+
state: {
169+
pagination,
170+
sorting,
171+
}
172+
//syntax 1
173+
onPaginationChange: (updater) => {
174+
setPagination(old => {
175+
const newPaginationValue = updater instanceof Function ? updater(old) : updater
176+
//do something with the new pagination value
177+
//...
178+
return newPaginationValue
179+
})
180+
},
181+
//syntax 2
182+
onSortingChange: (updater) => {
183+
const newSortingValue = updater instanceof Function ? updater(sorting) : updater
184+
//do something with the new sorting value
185+
//...
186+
setSorting(updater) //normal state update
187+
}
188+
})
189+
```
190+
191+
### State Types
192+
193+
All complex states in TanStack Table have their own TypeScript types that you can import and use. This can be handy for ensuring that you are using the correct data structures and properties for the state values that you are controlling.
194+
195+
```tsx
196+
import { useReactTable, SortingState } from '@tanstack/react-table'
197+
//...
198+
const [sorting, setSorting] = React.useState<SortingState[]>([
199+
{
200+
id: 'age', //you should get autocomplete for the `id` and `desc` properties
201+
desc: true,
202+
}
203+
])
204+
```

‎docs/guide/tables.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
title: Tables Guide
2+
title: Table Instance Guide
33
---
44

55
## API

0 commit comments

Comments
 (0)
Please sign in to comment.