docs-i18n 0.8.1 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/admin/dist/server/server.js +20 -20
- package/package.json +1 -1
- package/template/app/utils/content-loader.ts +4 -0
- package/template/app/utils/docs.server.ts +7 -0
- package/template/content/blog/en/announcing-query-v5.md +110 -0
- package/template/content/blog/en/hello-world.md +26 -0
- package/template/content/blog/en/i18n-best-practices.md +57 -0
- package/template/content/blog/en/react-query-vs-swr.md +100 -0
- package/template/content/blog/en/state-management-2024.md +143 -0
- package/template/content/blog/en/tanstack-router-1.0.md +121 -0
- package/template/content/blog/ja/announcing-query-v5.md +110 -0
- package/template/content/blog/ja/hello-world.md +26 -0
- package/template/content/blog/zh-hans/announcing-query-v5.md +93 -0
- package/template/content/blog/zh-hans/hello-world.md +26 -0
- package/template/content/docs-i18n/docs.config.json +25 -0
- package/template/content/docs-i18n/en/architecture.md +222 -0
- package/template/content/docs-i18n/en/configuration.md +331 -0
- package/template/content/docs-i18n/en/deployment.md +209 -0
- package/template/content/docs-i18n/en/getting-started.md +168 -0
- package/template/content/docs.config.json +25 -0
- package/template/content/en/admin.md +151 -0
- package/template/content/en/architecture.md +222 -0
- package/template/content/en/cli.md +269 -0
- package/template/content/en/configuration.md +331 -0
- package/template/content/en/deployment.md +209 -0
- package/template/content/en/getting-started.md +168 -0
- package/template/content/form/docs.config.json +18 -0
- package/template/content/form/en/guides/validation.md +175 -0
- package/template/content/form/en/installation.md +63 -0
- package/template/content/form/en/overview.md +71 -0
- package/template/content/form/en/quick-start.md +121 -0
- package/template/content/form/ja/installation.md +63 -0
- package/template/content/form/ja/overview.md +71 -0
- package/template/content/form/zh-hans/installation.md +63 -0
- package/template/content/form/zh-hans/overview.md +71 -0
- package/template/content/query/docs.config.json +32 -0
- package/template/content/query/en/guides/mutations.md +126 -0
- package/template/content/query/en/guides/pagination.md +98 -0
- package/template/content/query/en/guides/queries.md +120 -0
- package/template/content/query/en/installation.md +78 -0
- package/template/content/query/en/overview.md +72 -0
- package/template/content/query/en/quick-start.md +108 -0
- package/template/content/query/ja/installation.md +78 -0
- package/template/content/query/ja/overview.md +72 -0
- package/template/content/query/zh-hans/guides/mutations.md +126 -0
- package/template/content/query/zh-hans/guides/pagination.md +98 -0
- package/template/content/query/zh-hans/guides/queries.md +120 -0
- package/template/content/query/zh-hans/installation.md +95 -0
- package/template/content/query/zh-hans/overview.md +72 -0
- package/template/content/query/zh-hans/quick-start.md +108 -0
- package/template/content/router/docs.config.json +18 -0
- package/template/content/router/en/guides/routing-concepts.md +131 -0
- package/template/content/router/en/installation.md +57 -0
- package/template/content/router/en/overview.md +74 -0
- package/template/content/router/en/quick-start.md +88 -0
- package/template/content/router/ja/installation.md +57 -0
- package/template/content/router/ja/overview.md +78 -0
- package/template/content/router/zh-hans/guides/routing-concepts.md +131 -0
- package/template/content/router/zh-hans/installation.md +57 -0
- package/template/content/router/zh-hans/overview.md +81 -0
- package/template/content/router/zh-hans/quick-start.md +88 -0
- package/template/content/table/docs.config.json +18 -0
- package/template/content/table/en/guides/column-definitions.md +135 -0
- package/template/content/table/en/installation.md +56 -0
- package/template/content/table/en/overview.md +79 -0
- package/template/content/table/en/quick-start.md +112 -0
- package/template/content/table/ja/installation.md +56 -0
- package/template/content/table/ja/overview.md +79 -0
- package/template/content/table/zh-hans/installation.md +56 -0
- package/template/content/table/zh-hans/overview.md +79 -0
- package/template/content/virtual/docs.config.json +18 -0
- package/template/content/virtual/en/guides/dynamic-sizing.md +129 -0
- package/template/content/virtual/en/installation.md +57 -0
- package/template/content/virtual/en/overview.md +74 -0
- package/template/content/virtual/en/quick-start.md +114 -0
- package/template/content/virtual/ja/installation.md +57 -0
- package/template/content/virtual/ja/overview.md +74 -0
- package/template/content/virtual/zh-hans/installation.md +57 -0
- package/template/content/virtual/zh-hans/overview.md +74 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: インストール
|
|
3
|
+
description: プロジェクトに TanStack Query をインストールする方法
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# インストール
|
|
7
|
+
|
|
8
|
+
TanStack Query は、サポートされている各フレームワーク向けの npm パッケージとして利用できます。
|
|
9
|
+
|
|
10
|
+
## パッケージのインストール
|
|
11
|
+
|
|
12
|
+
フレームワークに合わせたパッケージを選択してください:
|
|
13
|
+
|
|
14
|
+
### React
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @tanstack/react-query
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pnpm add @tanstack/react-query
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
yarn add @tanstack/react-query
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
bun add @tanstack/react-query
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Vue
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm install @tanstack/vue-query
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Solid
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm install @tanstack/solid-query
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Svelte
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npm install @tanstack/svelte-query
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Angular
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
npm install @tanstack/angular-query-experimental
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## 必要要件
|
|
57
|
+
|
|
58
|
+
- TypeScript 4.7+(型推論のため)
|
|
59
|
+
- React 18+ / Vue 3+ / Solid 1.6+ / Svelte 4+
|
|
60
|
+
|
|
61
|
+
## Devtools
|
|
62
|
+
|
|
63
|
+
より良い開発体験のために、devtools のインストールもお勧めします:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
npm install @tanstack/react-query-devtools
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
> [!NOTE]
|
|
70
|
+
> Devtools は現在 React のみ対応しています。他のフレームワーク向けにはコミュニティ製の devtools があります。
|
|
71
|
+
|
|
72
|
+
## CDN
|
|
73
|
+
|
|
74
|
+
プロトタイピングには、CDN から TanStack Query を読み込めます:
|
|
75
|
+
|
|
76
|
+
```html
|
|
77
|
+
<script src="https://unpkg.com/@tanstack/react-query/build/umd/index.production.js"></script>
|
|
78
|
+
```
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: TanStack Query 概要
|
|
3
|
+
description: TS/JS、React、Vue、Solid、Svelte、Angular向けの強力な非同期状態管理
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# TanStack Query
|
|
7
|
+
|
|
8
|
+
TanStack Query(旧称 React Query)を使えば、Webアプリケーションにおけるデータの取得、キャッシュ、同期、更新が簡単に行えます。
|
|
9
|
+
|
|
10
|
+
## モチベーション
|
|
11
|
+
|
|
12
|
+
ほとんどのWebフレームワークには、データの取得や更新について統一的な方法が用意されていません。開発者は独自のデータ取得方法を考案するか、メタフレームワークを構築する必要があります。これは通常、コンポーネントベースの状態と副作用を組み合わせるか、汎用的な状態管理ライブラリを使って非同期データを管理することを意味します。
|
|
13
|
+
|
|
14
|
+
## 特徴
|
|
15
|
+
|
|
16
|
+
- **トランスポート/プロトコル/バックエンド非依存** のデータ取得(REST、GraphQL、Promiseなど何でも対応!)
|
|
17
|
+
- **自動キャッシュ** とリクエストの重複排除
|
|
18
|
+
- **自動再取得** — stale-while-revalidate戦略
|
|
19
|
+
- **ウィンドウフォーカス再取得** でデータを最新に保つ
|
|
20
|
+
- **ポーリング/リアルタイム** クエリ(間隔設定可能)
|
|
21
|
+
- **並列・依存クエリ** で複雑なデータ要件に対応
|
|
22
|
+
- **ミューテーション** — 楽観的更新をサポート
|
|
23
|
+
- **ページネーション・無限スクロール** を標準サポート
|
|
24
|
+
- **専用DevTools** でデバッグを支援
|
|
25
|
+
|
|
26
|
+
## サポートされるフレームワーク
|
|
27
|
+
|
|
28
|
+
TanStack Queryは以下のフレームワークをサポートしています:
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
// React
|
|
32
|
+
import { useQuery } from '@tanstack/react-query'
|
|
33
|
+
|
|
34
|
+
// Vue
|
|
35
|
+
import { useQuery } from '@tanstack/vue-query'
|
|
36
|
+
|
|
37
|
+
// Solid
|
|
38
|
+
import { createQuery } from '@tanstack/solid-query'
|
|
39
|
+
|
|
40
|
+
// Svelte
|
|
41
|
+
import { createQuery } from '@tanstack/svelte-query'
|
|
42
|
+
|
|
43
|
+
// Angular
|
|
44
|
+
import { injectQuery } from '@tanstack/angular-query-experimental'
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## クイック例
|
|
48
|
+
|
|
49
|
+
```tsx
|
|
50
|
+
import { useQuery } from '@tanstack/react-query'
|
|
51
|
+
|
|
52
|
+
function App() {
|
|
53
|
+
const { data, isLoading, error } = useQuery({
|
|
54
|
+
queryKey: ['todos'],
|
|
55
|
+
queryFn: () => fetch('/api/todos').then(res => res.json()),
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
if (isLoading) return <div>読み込み中...</div>
|
|
59
|
+
if (error) return <div>エラー:{error.message}</div>
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<ul>
|
|
63
|
+
{data.map(todo => (
|
|
64
|
+
<li key={todo.id}>{todo.title}</li>
|
|
65
|
+
))}
|
|
66
|
+
</ul>
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
> [!NOTE]
|
|
72
|
+
> TanStack Query v5は最新バージョンであり、APIの簡素化やTypeScriptサポートの改善など、大幅な改良が含まれています。
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 变更操作
|
|
3
|
+
description: 了解如何使用 TanStack Query 的变更操作创建、更新和删除数据
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 变更操作
|
|
7
|
+
|
|
8
|
+
与查询不同,变更操作通常用于创建/更新/删除数据或执行服务端副作用。为此,TanStack Query 导出了 `useMutation` Hook。
|
|
9
|
+
|
|
10
|
+
## 基本变更操作
|
|
11
|
+
|
|
12
|
+
```tsx
|
|
13
|
+
import { useMutation, useQueryClient } from '@tanstack/react-query'
|
|
14
|
+
|
|
15
|
+
function AddTodo() {
|
|
16
|
+
const queryClient = useQueryClient()
|
|
17
|
+
|
|
18
|
+
const mutation = useMutation({
|
|
19
|
+
mutationFn: (newTodo: { title: string }) => {
|
|
20
|
+
return fetch('/api/todos', {
|
|
21
|
+
method: 'POST',
|
|
22
|
+
body: JSON.stringify(newTodo),
|
|
23
|
+
headers: { 'Content-Type': 'application/json' },
|
|
24
|
+
}).then((res) => res.json())
|
|
25
|
+
},
|
|
26
|
+
onSuccess: () => {
|
|
27
|
+
// 使待办事项列表缓存失效并重新获取
|
|
28
|
+
queryClient.invalidateQueries({ queryKey: ['todos'] })
|
|
29
|
+
},
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<button
|
|
34
|
+
onClick={() => mutation.mutate({ title: 'New Todo' })}
|
|
35
|
+
disabled={mutation.isPending}
|
|
36
|
+
>
|
|
37
|
+
{mutation.isPending ? '添加中...' : '添加待办事项'}
|
|
38
|
+
</button>
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## 变更状态
|
|
44
|
+
|
|
45
|
+
在任意时刻,变更操作只能处于以下状态之一:
|
|
46
|
+
|
|
47
|
+
| 状态 | 描述 |
|
|
48
|
+
|---|---|
|
|
49
|
+
| `isIdle` | 变更操作处于空闲或初始/重置状态 |
|
|
50
|
+
| `isPending` | 变更操作正在执行 |
|
|
51
|
+
| `isError` | 变更操作遇到错误 |
|
|
52
|
+
| `isSuccess` | 变更操作成功,数据可用 |
|
|
53
|
+
|
|
54
|
+
## 乐观更新
|
|
55
|
+
|
|
56
|
+
乐观更新允许您在服务器确认变更之前更新 UI,提供更流畅的用户体验:
|
|
57
|
+
|
|
58
|
+
```tsx
|
|
59
|
+
const mutation = useMutation({
|
|
60
|
+
mutationFn: updateTodo,
|
|
61
|
+
onMutate: async (newTodo) => {
|
|
62
|
+
// 取消正在进行的重新获取,以避免覆盖乐观更新
|
|
63
|
+
await queryClient.cancelQueries({ queryKey: ['todos'] })
|
|
64
|
+
|
|
65
|
+
// 保存之前的值快照
|
|
66
|
+
const previousTodos = queryClient.getQueryData(['todos'])
|
|
67
|
+
|
|
68
|
+
// 乐观地更新为新值
|
|
69
|
+
queryClient.setQueryData(['todos'], (old: Todo[]) => [
|
|
70
|
+
...old,
|
|
71
|
+
{ ...newTodo, id: Date.now() },
|
|
72
|
+
])
|
|
73
|
+
|
|
74
|
+
// 返回包含快照值的上下文对象
|
|
75
|
+
return { previousTodos }
|
|
76
|
+
},
|
|
77
|
+
onError: (_err, _newTodo, context) => {
|
|
78
|
+
// 出错时回滚到之前的值
|
|
79
|
+
queryClient.setQueryData(['todos'], context?.previousTodos)
|
|
80
|
+
},
|
|
81
|
+
onSettled: () => {
|
|
82
|
+
// 无论成功或失败都重新获取
|
|
83
|
+
queryClient.invalidateQueries({ queryKey: ['todos'] })
|
|
84
|
+
},
|
|
85
|
+
})
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
> [!NOTE]
|
|
89
|
+
> `onMutate` 处理函数在变更函数之前运行,并接收相同的变量。这是执行乐观更新的最佳位置。
|
|
90
|
+
|
|
91
|
+
## 重试
|
|
92
|
+
|
|
93
|
+
默认情况下,TanStack Query 不会重试失败的变更操作。您可以为每个变更操作单独配置:
|
|
94
|
+
|
|
95
|
+
```tsx
|
|
96
|
+
const mutation = useMutation({
|
|
97
|
+
mutationFn: addTodo,
|
|
98
|
+
retry: 3, // 失败的变更操作重试 3 次
|
|
99
|
+
})
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## 变更回调
|
|
103
|
+
|
|
104
|
+
`useMutation` Hook 支持多个回调选项:
|
|
105
|
+
|
|
106
|
+
```tsx
|
|
107
|
+
useMutation({
|
|
108
|
+
mutationFn: addTodo,
|
|
109
|
+
onMutate: (variables) => {
|
|
110
|
+
// 在变更函数触发之前调用
|
|
111
|
+
// 接收变更函数将接收的相同变量
|
|
112
|
+
},
|
|
113
|
+
onError: (error, variables, context) => {
|
|
114
|
+
// 变更操作遇到错误时调用
|
|
115
|
+
},
|
|
116
|
+
onSuccess: (data, variables, context) => {
|
|
117
|
+
// 变更操作成功时调用
|
|
118
|
+
},
|
|
119
|
+
onSettled: (data, error, variables, context) => {
|
|
120
|
+
// 无论成功还是失败都会调用
|
|
121
|
+
},
|
|
122
|
+
})
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
> [!WARNING]
|
|
126
|
+
> `useMutation` 上的回调会在每个使用它的组件实例中触发。要确保副作用只执行一次,请使用 `mutate` 函数上的回调,或将变更操作提取到共享 Hook 中。
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 分页
|
|
3
|
+
description: 了解如何使用 TanStack Query 实现分页查询
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 分页
|
|
7
|
+
|
|
8
|
+
渲染分页数据是非常常见的 UI 模式,在 TanStack Query 中,只需将页面信息包含在查询键中即可"自然生效"。
|
|
9
|
+
|
|
10
|
+
## 基本分页示例
|
|
11
|
+
|
|
12
|
+
```tsx
|
|
13
|
+
const fetchProjects = async (page: number) => {
|
|
14
|
+
const res = await fetch(`/api/projects?page=${page}`)
|
|
15
|
+
return res.json()
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function Projects() {
|
|
19
|
+
const [page, setPage] = React.useState(1)
|
|
20
|
+
|
|
21
|
+
const { data, isPreviousData, isLoading } = useQuery({
|
|
22
|
+
queryKey: ['projects', page],
|
|
23
|
+
queryFn: () => fetchProjects(page),
|
|
24
|
+
placeholderData: keepPreviousData,
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<div>
|
|
29
|
+
{isLoading ? (
|
|
30
|
+
<div>加载中...</div>
|
|
31
|
+
) : (
|
|
32
|
+
<>
|
|
33
|
+
{data.projects.map((project) => (
|
|
34
|
+
<p key={project.id}>{project.name}</p>
|
|
35
|
+
))}
|
|
36
|
+
</>
|
|
37
|
+
)}
|
|
38
|
+
<div className="flex gap-2">
|
|
39
|
+
<button
|
|
40
|
+
onClick={() => setPage((old) => Math.max(old - 1, 1))}
|
|
41
|
+
disabled={page === 1}
|
|
42
|
+
>
|
|
43
|
+
上一页
|
|
44
|
+
</button>
|
|
45
|
+
<span>第 {page} 页</span>
|
|
46
|
+
<button
|
|
47
|
+
onClick={() => {
|
|
48
|
+
if (!isPreviousData && data.hasMore) {
|
|
49
|
+
setPage((old) => old + 1)
|
|
50
|
+
}
|
|
51
|
+
}}
|
|
52
|
+
disabled={isPreviousData || !data?.hasMore}
|
|
53
|
+
>
|
|
54
|
+
下一页
|
|
55
|
+
</button>
|
|
56
|
+
</div>
|
|
57
|
+
</>
|
|
58
|
+
)
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## 使用 `keepPreviousData`
|
|
63
|
+
|
|
64
|
+
`keepPreviousData` 选项对流畅的分页体验至关重要。启用后,即使查询键发生变化,在请求新数据时仍可使用上次成功获取的数据。
|
|
65
|
+
|
|
66
|
+
> [!NOTE]
|
|
67
|
+
> `keepPreviousData` 在 v5 中从 `previousData` 重命名而来。如果您是从 v4 迁移,请相应更新代码。
|
|
68
|
+
|
|
69
|
+
## 预取下一页
|
|
70
|
+
|
|
71
|
+
为了更流畅的用户体验,可以在用户导航之前预取下一页:
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
const queryClient = useQueryClient()
|
|
75
|
+
|
|
76
|
+
React.useEffect(() => {
|
|
77
|
+
if (data?.hasMore) {
|
|
78
|
+
queryClient.prefetchQuery({
|
|
79
|
+
queryKey: ['projects', page + 1],
|
|
80
|
+
queryFn: () => fetchProjects(page + 1),
|
|
81
|
+
})
|
|
82
|
+
}
|
|
83
|
+
}, [data, page, queryClient])
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## 无限查询
|
|
87
|
+
|
|
88
|
+
对于"加载更多"和无限滚动模式,TanStack Query 提供了 `useInfiniteQuery` Hook。详情请参阅[无限查询指南](/en/query/docs/guides/infinite-queries)。
|
|
89
|
+
|
|
90
|
+
| 功能 | `useQuery` + 分页 | `useInfiniteQuery` |
|
|
91
|
+
|---|---|---|
|
|
92
|
+
| 页面导航 | 上一页/下一页按钮 | 加载更多/无限滚动 |
|
|
93
|
+
| 数据结构 | 单页 | 累积页面 |
|
|
94
|
+
| 内存使用 | 较低(一页) | 较高(所有已加载页面) |
|
|
95
|
+
| URL 同步 | 简单 | 更复杂 |
|
|
96
|
+
|
|
97
|
+
> [!WARNING]
|
|
98
|
+
> 不要将 `useInfiniteQuery` 用于传统的页面导航。它专为"加载更多"模式设计,即之前加载的数据保持可见。
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 查询
|
|
3
|
+
description: 了解 TanStack Query 中查询的工作原理
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 查询
|
|
7
|
+
|
|
8
|
+
查询是对异步数据源的声明式依赖,与唯一键绑定。查询可以与任何基于 Promise 的方法(包括 GET 和 POST 方法)一起使用,从服务器获取数据。
|
|
9
|
+
|
|
10
|
+
## 查询基础
|
|
11
|
+
|
|
12
|
+
要在组件中订阅查询,至少需要传入一个唯一键和一个返回 Promise 的函数来调用查询 Hook:
|
|
13
|
+
|
|
14
|
+
<!-- ::start:react -->
|
|
15
|
+
|
|
16
|
+
```tsx
|
|
17
|
+
import { useQuery } from '@tanstack/react-query'
|
|
18
|
+
|
|
19
|
+
function Example() {
|
|
20
|
+
const { data, isLoading, error } = useQuery({
|
|
21
|
+
queryKey: ['todos'],
|
|
22
|
+
queryFn: fetchTodoList,
|
|
23
|
+
})
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
<!-- ::end:react -->
|
|
28
|
+
|
|
29
|
+
<!-- ::start:vue -->
|
|
30
|
+
|
|
31
|
+
```vue
|
|
32
|
+
<script setup>
|
|
33
|
+
import { useQuery } from '@tanstack/vue-query'
|
|
34
|
+
|
|
35
|
+
const { data, isLoading, error } = useQuery({
|
|
36
|
+
queryKey: ['todos'],
|
|
37
|
+
queryFn: fetchTodoList,
|
|
38
|
+
})
|
|
39
|
+
</script>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
<!-- ::end:vue -->
|
|
43
|
+
|
|
44
|
+
<!-- ::start:solid -->
|
|
45
|
+
|
|
46
|
+
```tsx
|
|
47
|
+
import { createQuery } from '@tanstack/solid-query'
|
|
48
|
+
|
|
49
|
+
function Example() {
|
|
50
|
+
const query = createQuery(() => ({
|
|
51
|
+
queryKey: ['todos'],
|
|
52
|
+
queryFn: fetchTodoList,
|
|
53
|
+
}))
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
<!-- ::end:solid -->
|
|
58
|
+
|
|
59
|
+
## 查询键
|
|
60
|
+
|
|
61
|
+
查询键用于唯一标识一个查询。它可以是一个简单的字符串,也可以是包含多个字符串和嵌套对象的数组:
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
// 简单字符串键
|
|
65
|
+
useQuery({ queryKey: ['todos'], ... })
|
|
66
|
+
|
|
67
|
+
// 带变量的键
|
|
68
|
+
useQuery({ queryKey: ['todo', todoId], ... })
|
|
69
|
+
|
|
70
|
+
// 带对象的键
|
|
71
|
+
useQuery({ queryKey: ['todos', { type: 'done', page: 1 }], ... })
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## 查询函数
|
|
75
|
+
|
|
76
|
+
查询函数可以是任何返回 Promise 的函数。返回的 Promise 应该解析数据或抛出错误:
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
const { data } = useQuery({
|
|
80
|
+
queryKey: ['todos'],
|
|
81
|
+
queryFn: async () => {
|
|
82
|
+
const response = await fetch('/api/todos')
|
|
83
|
+
if (!response.ok) {
|
|
84
|
+
throw new Error('Network response was not ok')
|
|
85
|
+
}
|
|
86
|
+
return response.json()
|
|
87
|
+
},
|
|
88
|
+
})
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## 查询状态
|
|
92
|
+
|
|
93
|
+
在任意时刻,查询可以处于以下状态之一:
|
|
94
|
+
|
|
95
|
+
- **`isPending`** — 查询尚无数据
|
|
96
|
+
- **`isError`** — 查询遇到错误
|
|
97
|
+
- **`isSuccess`** — 查询成功,数据可用
|
|
98
|
+
|
|
99
|
+
```tsx
|
|
100
|
+
function Todos() {
|
|
101
|
+
const { data, isPending, isError, error } = useQuery({
|
|
102
|
+
queryKey: ['todos'],
|
|
103
|
+
queryFn: fetchTodos,
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
if (isPending) return <span>加载中...</span>
|
|
107
|
+
if (isError) return <span>错误:{error.message}</span>
|
|
108
|
+
|
|
109
|
+
return (
|
|
110
|
+
<ul>
|
|
111
|
+
{data.map((todo) => (
|
|
112
|
+
<li key={todo.id}>{todo.title}</li>
|
|
113
|
+
))}
|
|
114
|
+
</ul>
|
|
115
|
+
)
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
> [!NOTE]
|
|
120
|
+
> 在 TanStack Query v5 中,`isLoading` 已被重命名为 `isPending` 以保持一致性。
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 安装
|
|
3
|
+
description: 了解如何在项目中安装和配置 TanStack Query
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 安装
|
|
7
|
+
|
|
8
|
+
TanStack Query 兼容 React v18+,支持 ReactDOM 和 React Native。
|
|
9
|
+
|
|
10
|
+
## 安装依赖
|
|
11
|
+
|
|
12
|
+
使用你喜欢的包管理器安装:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install @tanstack/react-query
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
或者使用其他包管理器:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# pnpm
|
|
22
|
+
pnpm add @tanstack/react-query
|
|
23
|
+
|
|
24
|
+
# yarn
|
|
25
|
+
yarn add @tanstack/react-query
|
|
26
|
+
|
|
27
|
+
# bun
|
|
28
|
+
bun add @tanstack/react-query
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## 配置 QueryClient
|
|
32
|
+
|
|
33
|
+
在应用根组件中创建一个 `QueryClient` 实例,并用 `QueryClientProvider` 包裹应用:
|
|
34
|
+
|
|
35
|
+
```tsx
|
|
36
|
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
|
37
|
+
|
|
38
|
+
// 创建一个 QueryClient 实例
|
|
39
|
+
const queryClient = new QueryClient({
|
|
40
|
+
defaultOptions: {
|
|
41
|
+
queries: {
|
|
42
|
+
staleTime: 1000 * 60, // 1 分钟
|
|
43
|
+
retry: 1,
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
function App() {
|
|
49
|
+
return (
|
|
50
|
+
<QueryClientProvider client={queryClient}>
|
|
51
|
+
<YourApp />
|
|
52
|
+
</QueryClientProvider>
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## 安装开发工具
|
|
58
|
+
|
|
59
|
+
开发工具有助于调试和可视化查询状态。推荐在开发环境中使用:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
npm install @tanstack/react-query-devtools
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
|
|
67
|
+
|
|
68
|
+
function App() {
|
|
69
|
+
return (
|
|
70
|
+
<QueryClientProvider client={queryClient}>
|
|
71
|
+
<YourApp />
|
|
72
|
+
<ReactQueryDevtools initialIsOpen={false} />
|
|
73
|
+
</QueryClientProvider>
|
|
74
|
+
)
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
> [!NOTE]
|
|
79
|
+
> 开发工具仅在开发环境中加载。在生产构建中会自动被 tree-shake 移除,不会增加生产包体积。
|
|
80
|
+
|
|
81
|
+
## TypeScript 配置
|
|
82
|
+
|
|
83
|
+
TanStack Query 使用 TypeScript 编写,开箱即用提供完整的类型支持。建议使用 TypeScript 4.7 或更高版本以获得最佳体验。
|
|
84
|
+
|
|
85
|
+
```json
|
|
86
|
+
{
|
|
87
|
+
"compilerOptions": {
|
|
88
|
+
"strict": true,
|
|
89
|
+
"moduleResolution": "bundler"
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
> [!WARNING]
|
|
95
|
+
> 请确保你的 TypeScript 版本不低于 4.7。旧版本可能无法正确推断某些类型。
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: TanStack Query 概述
|
|
3
|
+
description: 强大的异步状态管理,支持 TS/JS、React、Vue、Solid、Svelte 和 Angular
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# TanStack Query
|
|
7
|
+
|
|
8
|
+
TanStack Query(前身为 React Query)让您在 Web 应用中轻松实现数据获取、缓存、同步和更新服务器状态。
|
|
9
|
+
|
|
10
|
+
## 动机
|
|
11
|
+
|
|
12
|
+
大多数核心 Web 框架并没有提供一套统一的数据获取或更新方案。开发者往往需要自己构建元框架来封装数据获取的逻辑,或者自行发明数据获取方式。这通常意味着将基于组件的状态和副作用拼凑在一起,或者使用通用的状态管理库来存储和提供异步数据。
|
|
13
|
+
|
|
14
|
+
## 特性
|
|
15
|
+
|
|
16
|
+
- **传输/协议/后端无关** 的数据获取(REST、GraphQL、Promise 等皆可!)
|
|
17
|
+
- **自动缓存** 并支持请求去重
|
|
18
|
+
- **自动重新获取** 采用 stale-while-revalidate 策略
|
|
19
|
+
- **窗口焦点重新获取** 保持数据最新
|
|
20
|
+
- **轮询/实时** 查询,可配置间隔
|
|
21
|
+
- **并行和依赖查询** 满足复杂数据需求
|
|
22
|
+
- **变更操作** 支持乐观更新
|
|
23
|
+
- **分页和无限滚动** 开箱即用
|
|
24
|
+
- **专用开发工具** 便于调试
|
|
25
|
+
|
|
26
|
+
## 支持的框架
|
|
27
|
+
|
|
28
|
+
TanStack Query 支持以下框架:
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
// React
|
|
32
|
+
import { useQuery } from '@tanstack/react-query'
|
|
33
|
+
|
|
34
|
+
// Vue
|
|
35
|
+
import { useQuery } from '@tanstack/vue-query'
|
|
36
|
+
|
|
37
|
+
// Solid
|
|
38
|
+
import { createQuery } from '@tanstack/solid-query'
|
|
39
|
+
|
|
40
|
+
// Svelte
|
|
41
|
+
import { createQuery } from '@tanstack/svelte-query'
|
|
42
|
+
|
|
43
|
+
// Angular
|
|
44
|
+
import { injectQuery } from '@tanstack/angular-query-experimental'
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## 快速示例
|
|
48
|
+
|
|
49
|
+
```tsx
|
|
50
|
+
import { useQuery } from '@tanstack/react-query'
|
|
51
|
+
|
|
52
|
+
function App() {
|
|
53
|
+
const { data, isLoading, error } = useQuery({
|
|
54
|
+
queryKey: ['todos'],
|
|
55
|
+
queryFn: () => fetch('/api/todos').then(res => res.json()),
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
if (isLoading) return <div>加载中...</div>
|
|
59
|
+
if (error) return <div>错误:{error.message}</div>
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<ul>
|
|
63
|
+
{data.map(todo => (
|
|
64
|
+
<li key={todo.id}>{todo.title}</li>
|
|
65
|
+
))}
|
|
66
|
+
</ul>
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
> [!NOTE]
|
|
72
|
+
> TanStack Query v5 是最新版本,包含大量改进,例如简化的 API 和更好的 TypeScript 支持。
|