Skip to content

Commit b8392cd

Browse files
committed
docs: update documentation translations
1 parent 947ca58 commit b8392cd

File tree

1 file changed

+167
-0
lines changed

1 file changed

+167
-0
lines changed

docs/zh-hans/faq.md

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
---
2+
source-updated-at: '2024-03-28T21:06:30.000Z'
3+
translation-updated-at: '2025-05-02T16:50:14.598Z'
4+
title: 常见问题解答
5+
---
6+
## 如何避免无限渲染循环?
7+
8+
如果你在使用 React,有一个常见的陷阱会导致无限渲染。如果你未能为 `columns``data``state` 提供稳定的引用,React 会在表格状态发生任何变化时进入无限重新渲染循环。
9+
10+
为什么会这样?这是 TanStack Table 的 bug 吗?**不是***这是 React 的基本工作原理*,正确管理你的列、数据和状态可以避免这个问题。
11+
12+
TanStack Table 的设计会在传入表格的 `data``columns` 发生变化时,或表格的任何状态发生变化时触发重新渲染。
13+
14+
> 未能为 `columns``data` 提供稳定的引用会导致无限重新渲染循环。
15+
16+
### 陷阱 1:在每次渲染时创建新的列或数据
17+
18+
```js
19+
export default function MyComponent() {
20+
//😵 错误:这将导致无限重新渲染循环,因为 `columns` 在每次渲染时被重新定义为一个新数组!
21+
const columns = [
22+
// ...
23+
];
24+
25+
//😵 错误:这将导致无限重新渲染循环,因为 `data` 在每次渲染时被重新定义为一个新数组!
26+
const data = [
27+
// ...
28+
];
29+
30+
//❌ 列和数据在 `useReactTable` 的同一作用域内定义且没有稳定引用,会导致无限循环!
31+
const table = useReactTable({
32+
columns,
33+
data,
34+
});
35+
36+
return <table>...</table>;
37+
}
38+
```
39+
40+
### 解决方案 1:使用 useMemo 或 useState 提供稳定引用
41+
42+
在 React 中,你可以通过将变量定义在组件外部/上方,或使用 `useMemo``useState`,或使用第三方状态管理库(如 Redux 或 React Query 😉)来提供“稳定”引用。
43+
44+
```js
45+
//✅ 正确:在组件外部定义列
46+
const columns = [
47+
// ...
48+
];
49+
50+
//✅ 正确:在组件外部定义数据
51+
const data = [
52+
// ...
53+
];
54+
55+
// 通常更实际的做法是在组件内部定义列和数据,因此使用 `useMemo` 或 `useState` 来提供稳定引用
56+
export default function MyComponent() {
57+
//✅ 正确:这不会导致无限重新渲染循环,因为 `columns` 是一个稳定引用
58+
const columns = useMemo(() => [
59+
// ...
60+
], []);
61+
62+
//✅ 正确:这不会导致无限重新渲染循环,因为 `data` 是一个稳定引用
63+
const [data, setData] = useState(() => [
64+
// ...
65+
]);
66+
67+
// 列和数据具有稳定引用,不会导致无限循环!
68+
const table = useReactTable({
69+
columns,
70+
data,
71+
});
72+
73+
return <table>...</table>;
74+
}
75+
```
76+
77+
### 陷阱 2:原地修改列或数据
78+
79+
即使你为初始的 `columns``data` 提供了稳定引用,如果你原地修改它们,仍然可能陷入无限循环。这是一个常见的陷阱,一开始可能不会注意到。像简单的内联 `data.filter()` 这样的操作如果不小心处理,也可能导致无限循环。
80+
81+
```js
82+
export default function MyComponent() {
83+
//✅ 正确
84+
const columns = useMemo(() => [
85+
// ...
86+
], []);
87+
88+
//✅ 正确(React Query 会自动为数据提供稳定引用)
89+
const { data, isLoading } = useQuery({
90+
//...
91+
});
92+
93+
const table = useReactTable({
94+
columns,
95+
//❌ 错误:这将导致无限重新渲染循环,因为 `data` 被原地修改(破坏了稳定引用)
96+
data: data?.filter(d => d.isActive) ?? [],
97+
});
98+
99+
return <table>...</table>;
100+
}
101+
```
102+
103+
### 解决方案 2:缓存数据转换
104+
105+
为了避免无限循环,你应该始终缓存数据转换操作。可以使用 `useMemo` 或类似方法实现。
106+
107+
```js
108+
export default function MyComponent() {
109+
//✅ 正确
110+
const columns = useMemo(() => [
111+
// ...
112+
], []);
113+
114+
//✅ 正确
115+
const { data, isLoading } = useQuery({
116+
//...
117+
});
118+
119+
//✅ 正确:这不会导致无限重新渲染循环,因为 `filteredData` 被缓存了
120+
const filteredData = useMemo(() => data?.filter(d => d.isActive) ?? [], [data]);
121+
122+
const table = useReactTable({
123+
columns,
124+
data: filteredData, // 稳定引用!
125+
});
126+
127+
return <table>...</table>;
128+
}
129+
```
130+
131+
### React Forget
132+
133+
当 React Forget 发布后,这些问题可能会成为过去。或者直接使用 Solid.js... 🤓
134+
135+
## 如何在数据变化时阻止表格状态自动重置?
136+
137+
大多数插件使用的状态在数据源变化时*通常*应该重置,但有时如果你在外部过滤数据、不可变地编辑数据时查看数据,或只是对数据做任何不希望触发表格状态自动重置的外部操作时,你需要阻止这种自动重置行为。
138+
139+
对于这些情况,每个插件都提供了禁用状态自动重置的方法。通过将它们中的任何一个设置为 `false`,你可以阻止自动重置被触发。
140+
141+
以下是一个基于 React 的示例,展示了在编辑表格的 `data` 源时阻止所有状态自动重置的方法:
142+
143+
```js
144+
const [data, setData] = React.useState([])
145+
const skipPageResetRef = React.useRef()
146+
147+
const updateData = newData => {
148+
// 当通过此函数更新数据时,设置一个标志
149+
// 以禁用所有自动重置
150+
skipPageResetRef.current = true
151+
152+
setData(newData)
153+
}
154+
155+
React.useEffect(() => {
156+
// 表格更新后,始终移除标志
157+
skipPageResetRef.current = false
158+
})
159+
160+
useReactTable({
161+
...
162+
autoResetPageIndex: !skipPageResetRef.current,
163+
autoResetExpanded: !skipPageResetRef.current,
164+
})
165+
```
166+
167+
现在,当我们更新数据时,上述表格状态将不会自动重置!

0 commit comments

Comments
 (0)