(() => ({
+ enabled: this.postIdSignal() > 0,
+ queryKey: [`/posts/${this.postIdSignal()}`],
+ }))
+ // ...
+}
+```
+
+如果需要覆盖默认的 queryFn,只需像平常那样提供你自己的查询函数即可。
diff --git a/docs/zh-hans/framework/angular/guides/dependent-queries.md b/docs/zh-hans/framework/angular/guides/dependent-queries.md
new file mode 100644
index 00000000000..42f09d7d72f
--- /dev/null
+++ b/docs/zh-hans/framework/angular/guides/dependent-queries.md
@@ -0,0 +1,66 @@
+---
+source-updated-at: '2024-01-26T03:31:25.000Z'
+translation-updated-at: '2025-05-06T05:07:06.536Z'
+id: dependent-queries
+title: 依赖查询
+---
+
+## 依赖查询 (Dependent Query)
+
+依赖查询(或串行查询)需要等待前一个查询完成才能执行。实现这一功能非常简单,只需使用 `enabled` 选项来告知查询何时可以运行:
+
+```ts
+// 获取用户信息
+userQuery = injectQuery(() => ({
+ queryKey: ['user', email],
+ queryFn: getUserByEmail,
+}))
+
+// 然后获取用户的项目列表
+projectsQuery = injectQuery(() => ({
+ queryKey: ['projects', this.userQuery.data()?.id],
+ queryFn: getProjectsByUser,
+ // 该查询只有在用户ID存在时才会执行
+ enabled: !!this.userQuery.data()?.id,
+}))
+```
+
+`projects` 查询会以以下状态开始:
+
+```tsx
+status: 'pending'
+isPending: true
+fetchStatus: 'idle'
+```
+
+一旦 `user` 数据可用,`projects` 查询将被 `enabled` 并转为:
+
+```tsx
+status: 'pending'
+isPending: true
+fetchStatus: 'fetching'
+```
+
+当项目数据获取完成后,状态会变为:
+
+```tsx
+status: 'success'
+isPending: false
+fetchStatus: 'idle'
+```
+
+## injectQueries 依赖查询
+
+动态并行查询 —— `injectQueries` 也可以依赖于前一个查询,实现方式如下:
+
+```ts
+// injectQueries 功能正在 Angular Query 中开发
+```
+
+**注意**:`injectQueries` 返回的是**查询结果数组**
+
+## 关于性能的说明
+
+依赖查询本质上会形成一种[请求瀑布流 (request waterfall)](./request-waterfalls.md),这会损害性能。假设两个查询耗时相同,串行执行总是比并行执行多花一倍时间,对于高延迟的客户端尤为不利。如果可能,最好重构后端 API 使两个查询能并行获取,尽管这在实际中不一定可行。
+
+在上面的例子中,与其先获取 `getUserByEmail` 才能调用 `getProjectsByUser`,不如新增一个 `getProjectsByUserEmail` 查询来消除瀑布流。
diff --git a/docs/zh-hans/framework/angular/guides/disabling-queries.md b/docs/zh-hans/framework/angular/guides/disabling-queries.md
new file mode 100644
index 00000000000..f71b46d1a7a
--- /dev/null
+++ b/docs/zh-hans/framework/angular/guides/disabling-queries.md
@@ -0,0 +1,120 @@
+---
+source-updated-at: '2025-03-01T21:43:55.000Z'
+translation-updated-at: '2025-05-06T05:06:44.473Z'
+id: disabling-queries
+title: 禁用/暂停查询
+---
+
+如果你希望阻止某个查询自动执行,可以使用 `enabled = false` 选项。该选项也支持传入返回布尔值的回调函数。
+
+当 `enabled` 为 `false` 时:
+
+- 如果查询存在缓存数据,则初始化状态为 `status === 'success'` 或 `isSuccess`
+- 如果查询没有缓存数据,则初始化状态为 `status === 'pending'` 且 `fetchStatus === 'idle'`
+- 查询不会在挂载时自动获取数据
+- 查询不会在后台自动重新获取数据
+- 查询会忽略 query client 的 `invalidateQueries` 和 `refetchQueries` 调用(这些调用通常会导致查询重新获取数据)
+- 通过 `injectQuery` 返回的 `refetch` 可用于手动触发查询获取数据(但无法与 `skipToken` 配合使用)
+
+> TypeScript 用户可考虑使用 [skipToken](#typesafe-disabling-of-queries-using-skiptoken) 作为 `enabled = false` 的替代方案
+
+```angular-ts
+@Component({
+ selector: 'todos',
+ template: `
+
Fetch Todos
+
+ @if (query.data()) {
+
+ @for (todo of query.data(); track todo.id) {
+ {{ todo.title }}
+ }
+
+ } @else {
+ @if (query.isError()) {
+
Error: {{ query.error().message }}
+ } @else if (query.isLoading()) {
+
Loading...
+ } @else if (!query.isLoading() && !query.isError()) {
+
Not ready ...
+ }
+ }
+
+
{{ query.isLoading() ? 'Fetching...' : '' }}
+
`,
+})
+export class TodosComponent {
+ query = injectQuery(() => ({
+ queryKey: ['todos'],
+ queryFn: fetchTodoList,
+ enabled: false,
+ }))
+}
+```
+
+永久禁用查询会使你无法使用 TanStack Query 的许多优秀特性(如后台重新获取),这也不符合惯用模式。这会让你从声明式模式(定义查询运行依赖条件)退回到命令式模式(点击按钮时才获取数据),且无法向 `refetch` 传递参数。通常你需要的只是一个延迟初始获取的惰性查询:
+
+## 惰性查询
+
+`enabled` 选项不仅能永久禁用查询,还能实现动态启用/禁用。典型场景是筛选表单——只有当用户输入筛选值后才发起首次请求:
+
+```angular-ts
+@Component({
+ selector: 'todos',
+ template: `
+
+ // 🚀 应用筛选条件时将启用并执行查询
+
+
+
+ `,
+})
+export class TodosComponent {
+ filter = signal('')
+
+ todosQuery = injectQuery(() => ({
+ queryKey: ['todos', this.filter()],
+ queryFn: () => fetchTodos(this.filter()),
+ enabled: !!this.filter(),
+ }))
+}
+```
+
+### isLoading (原名为 `isInitialLoading`)
+
+惰性查询会始终处于 `status: 'pending'` 状态,因为 `pending` 表示尚无数据。虽然技术上是正确的,但由于当前并未获取数据(查询未被 _启用_),这个状态可能不适合用来显示加载指示器。
+
+对于禁用或惰性查询,可以使用 `isLoading` 标志。这是一个衍生标志,由以下条件计算得出:
+
+`isPending && isFetching`
+
+因此只有当查询首次获取数据时才会返回 `true`。
+
+## 使用 `skipToken` 实现类型安全的查询禁用
+
+TypeScript 用户可以使用 `skipToken` 禁用查询。适用于需要根据条件禁用查询,同时保持类型安全的场景。
+
+> 重要提示:`injectQuery` 返回的 `refetch` 无法与 `skipToken` 配合使用。除此之外,`skipToken` 的行为与 `enabled: false` 完全一致。
+
+```angular-ts
+import { skipToken, injectQuery } from '@tanstack/query-angular'
+
+@Component({
+ selector: 'todos',
+ template: `
+
+ // 🚀 应用筛选条件时将启用并执行查询
+
+
+
+ `,
+})
+export class TodosComponent {
+ filter = signal('')
+
+ todosQuery = injectQuery(() => ({
+ queryKey: ['todos', this.filter()],
+ queryFn: this.filter() ? () => fetchTodos(this.filter()) : skipToken,
+ }))
+}
+```
diff --git a/docs/zh-hans/framework/angular/guides/does-this-replace-client-state.md b/docs/zh-hans/framework/angular/guides/does-this-replace-client-state.md
new file mode 100644
index 00000000000..0bcd519fecb
--- /dev/null
+++ b/docs/zh-hans/framework/angular/guides/does-this-replace-client-state.md
@@ -0,0 +1,11 @@
+---
+source-updated-at: '2024-01-26T03:31:25.000Z'
+translation-updated-at: '2025-05-06T04:58:12.575Z'
+id: does-this-replace-client-state
+title: Does TanStack Query replace global state managers?
+ref: docs/zh-hans/framework/react/guides/does-this-replace-client-state.md
+replace:
+ useQuery: injectQuery
+ useMutation: injectMutation
+ hook: function
+---
diff --git a/docs/zh-hans/framework/angular/guides/filters.md b/docs/zh-hans/framework/angular/guides/filters.md
new file mode 100644
index 00000000000..f2a8878f4b1
--- /dev/null
+++ b/docs/zh-hans/framework/angular/guides/filters.md
@@ -0,0 +1,7 @@
+---
+source-updated-at: '2024-01-26T03:31:25.000Z'
+translation-updated-at: '2025-05-06T04:58:12.518Z'
+id: filters
+title: Filters
+ref: docs/zh-hans/framework/react/guides/filters.md
+---
diff --git a/docs/zh-hans/framework/angular/guides/important-defaults.md b/docs/zh-hans/framework/angular/guides/important-defaults.md
new file mode 100644
index 00000000000..af2707ee0bf
--- /dev/null
+++ b/docs/zh-hans/framework/angular/guides/important-defaults.md
@@ -0,0 +1,16 @@
+---
+source-updated-at: '2024-01-26T03:31:25.000Z'
+translation-updated-at: '2025-05-06T04:58:12.464Z'
+id: important-defaults
+title: Important Defaults
+ref: docs/zh-hans/framework/react/guides/important-defaults.md
+replace:
+ React: Angular
+ react-query: angular-query
+ useQuery: injectQuery
+ useInfiniteQuery: injectInfiniteQuery
+ useMemo and useCallback: setting signal values
+---
+
+[//]: # 'Materials'
+[//]: # 'Materials'
diff --git a/docs/zh-hans/framework/angular/guides/infinite-queries.md b/docs/zh-hans/framework/angular/guides/infinite-queries.md
new file mode 100644
index 00000000000..3522a7faa84
--- /dev/null
+++ b/docs/zh-hans/framework/angular/guides/infinite-queries.md
@@ -0,0 +1,246 @@
+---
+source-updated-at: '2024-07-19T09:36:35.000Z'
+translation-updated-at: '2025-05-06T05:05:56.640Z'
+id: infinite-queries
+title: 无限查询
+---
+
+## 无限查询 (Infinite Queries)
+
+能够以增量方式"加载更多"数据到现有数据集或实现"无限滚动"的列表渲染是一种非常常见的 UI 模式。TanStack Query 为此提供了一个名为 `injectInfiniteQuery` 的 `injectQuery` 变体,专门用于查询这类列表。
+
+使用 `injectInfiniteQuery` 时,您会注意到以下几点不同:
+
+- `data` 现在是一个包含无限查询数据的对象:
+ - `data.pages` 数组包含已获取的页面
+ - `data.pageParams` 数组包含用于获取页面的参数
+- 现在提供了 `fetchNextPage` 和 `fetchPreviousPage` 函数(必须实现 `fetchNextPage`)
+- 新增了 `initialPageParam` 选项(必须指定初始页面参数)
+- 提供了 `getNextPageParam` 和 `getPreviousPageParam` 选项,用于确定是否有更多数据要加载以及获取这些数据所需的信息。这些信息会作为额外参数传递给查询函数
+- 新增了 `hasNextPage` 布尔值,当 `getNextPageParam` 返回值不为 `null` 或 `undefined` 时为 `true`
+- 新增了 `hasPreviousPage` 布尔值,当 `getPreviousPageParam` 返回值不为 `null` 或 `undefined` 时为 `true`
+- 新增了 `isFetchingNextPage` 和 `isFetchingPreviousPage` 布尔值,用于区分后台刷新状态和加载更多状态
+
+> 注意:选项 `initialData` 或 `placeholderData` 需要符合具有 `data.pages` 和 `data.pageParams` 属性的对象结构。
+
+## 示例
+
+假设我们有一个 API,它基于 `cursor` 索引每次返回 3 个 `projects` 页面,同时返回可用于获取下一组项目的游标:
+
+```tsx
+fetch('/api/projects?cursor=0')
+// { data: [...], nextCursor: 3}
+fetch('/api/projects?cursor=3')
+// { data: [...], nextCursor: 6}
+fetch('/api/projects?cursor=6')
+// { data: [...], nextCursor: 9}
+fetch('/api/projects?cursor=9')
+// { data: [...] }
+```
+
+通过这些信息,我们可以创建一个"加载更多"的 UI:
+
+- 默认情况下等待 `injectInfiniteQuery` 请求第一组数据
+- 在 `getNextPageParam` 中返回下一个查询的信息
+- 调用 `fetchNextPage` 函数
+
+```angular-ts
+import { Component, computed, inject } from '@angular/core'
+import { injectInfiniteQuery } from '@tanstack/angular-query-experimental'
+import { lastValueFrom } from 'rxjs'
+import { ProjectsService } from './projects-service'
+
+@Component({
+ selector: 'example',
+ templateUrl: './example.component.html',
+})
+export class Example {
+ projectsService = inject(ProjectsService)
+
+ query = injectInfiniteQuery(() => ({
+ queryKey: ['projects'],
+ queryFn: async ({ pageParam }) => {
+ return lastValueFrom(this.projectsService.getProjects(pageParam))
+ },
+ initialPageParam: 0,
+ getPreviousPageParam: (firstPage) => firstPage.previousId ?? undefined,
+ getNextPageParam: (lastPage) => lastPage.nextId ?? undefined,
+ maxPages: 3,
+ }))
+
+ nextButtonDisabled = computed(
+ () => !this.#hasNextPage() || this.#isFetchingNextPage(),
+ )
+ nextButtonText = computed(() =>
+ this.#isFetchingNextPage()
+ ? '正在加载更多...'
+ : this.#hasNextPage()
+ ? '加载更新'
+ : '已加载全部内容',
+ )
+
+ #hasNextPage = this.query.hasNextPage
+ #isFetchingNextPage = this.query.isFetchingNextPage
+}
+```
+
+```angular-html
+
+ @if (query.isPending()) {
+
加载中...
+ } @else if (query.isError()) {
+
错误: {{ query?.error().message }}
+ } @else { @for (page of query?.data().pages; track $index) { @for (project of
+ page.data; track project.id) {
+
{{ project.name }} {{ project.id }}
+ } }
+
+
+ {{ nextButtonText() }}
+
+
+ }
+
+```
+
+必须理解的是,在后台正在进行数据获取时调用 `fetchNextPage` 有可能覆盖正在后台刷新的数据。当同时渲染列表和触发 `fetchNextPage` 时,这种情况变得尤为关键。
+
+请记住,一个 InfiniteQuery 只能有一个正在进行的获取操作。所有页面共享单个缓存条目,尝试同时进行两次获取可能会导致数据覆盖。
+
+如果您希望启用并行获取,可以在 `fetchNextPage` 中使用 `{ cancelRefetch: false }` 选项(默认为 true)。
+
+为了确保查询过程无冲突,强烈建议检查查询是否不处于 `isFetching` 状态,特别是当用户不会直接控制该调用时。
+
+```angular-ts
+@Component({
+ template: ` `,
+})
+export class Example {
+ query = injectInfiniteQuery(() => ({
+ queryKey: ['projects'],
+ queryFn: async ({ pageParam }) => {
+ return lastValueFrom(this.projectsService.getProjects(pageParam))
+ },
+ }))
+
+ fetchNextPage() {
+ // 如果正在获取,则不执行任何操作
+ if (this.query.isFetching()) return
+ this.query.fetchNextPage()
+ }
+}
+```
+
+## 当无限查询需要重新获取时会发生什么?
+
+当无限查询变为 `stale` 并需要重新获取时,每组数据会从第一组开始`顺序`获取。这确保了即使底层数据发生变更,我们也不会使用过期的游标,从而避免获取重复记录或跳过记录。如果无限查询的结果从 queryCache 中移除,分页将从初始状态重新开始,仅请求初始组。
+
+## 如何实现双向无限列表?
+
+双向列表可以通过使用 `getPreviousPageParam`、`fetchPreviousPage`、`hasPreviousPage` 和 `isFetchingPreviousPage` 属性和函数来实现。
+
+```ts
+query = injectInfiniteQuery(() => ({
+ queryKey: ['projects'],
+ queryFn: fetchProjects,
+ getNextPageParam: (lastPage, pages) => lastPage.nextCursor,
+ getPreviousPageParam: (firstPage, pages) => firstPage.prevCursor,
+}))
+```
+
+## 如何以相反顺序显示页面?
+
+有时您可能希望以相反的顺序显示页面。这种情况下,可以使用 `select` 选项:
+
+```ts
+query = injectInfiniteQuery(() => ({
+ queryKey: ['projects'],
+ queryFn: fetchProjects,
+ select: (data) => ({
+ pages: [...data.pages].reverse(),
+ pageParams: [...data.pageParams].reverse(),
+ }),
+}))
+```
+
+## 如何手动更新无限查询?
+
+### 手动移除第一页:
+
+```tsx
+queryClient.setQueryData(['projects'], (data) => ({
+ pages: data.pages.slice(1),
+ pageParams: data.pageParams.slice(1),
+}))
+```
+
+### 手动从单个页面中移除某个值:
+
+```tsx
+const newPagesArray =
+ oldPagesArray?.pages.map((page) =>
+ page.filter((val) => val.id !== updatedId),
+ ) ?? []
+
+queryClient.setQueryData(['projects'], (data) => ({
+ pages: newPagesArray,
+ pageParams: data.pageParams,
+}))
+```
+
+### 仅保留第一页:
+
+```tsx
+queryClient.setQueryData(['projects'], (data) => ({
+ pages: data.pages.slice(0, 1),
+ pageParams: data.pageParams.slice(0, 1),
+}))
+```
+
+请确保始终保持 pages 和 pageParams 的相同数据结构!
+
+## 如何限制页面数量?
+
+在某些使用场景中,您可能希望限制查询数据中存储的页面数量以提高性能和用户体验:
+
+- 当用户可以加载大量页面时(内存使用)
+- 当需要重新获取包含数十个页面的无限查询时(网络使用:所有页面都会顺序获取)
+
+解决方案是使用"有限无限查询"。这可以通过结合使用 `maxPages` 选项与 `getNextPageParam` 和 `getPreviousPageParam` 来实现,以便在需要时双向获取页面。
+
+在以下示例中,查询数据 pages 数组中仅保留 3 个页面。如果需要重新获取,只会顺序重新获取 3 个页面。
+
+```ts
+injectInfiniteQuery(() => ({
+ queryKey: ['projects'],
+ queryFn: fetchProjects,
+ initialPageParam: 0,
+ getNextPageParam: (lastPage, pages) => lastPage.nextCursor,
+ getPreviousPageParam: (firstPage, pages) => firstPage.prevCursor,
+ maxPages: 3,
+}))
+```
+
+## 如果我的 API 不返回游标怎么办?
+
+如果您的 API 不返回游标,您可以使用 `pageParam` 作为游标。因为 `getNextPageParam` 和 `getPreviousPageParam` 也会获取当前页面的 `pageParam`,所以您可以用它来计算下一个/上一个页面参数。
+
+```ts
+injectInfiniteQuery(() => ({
+ queryKey: ['projects'],
+ queryFn: fetchProjects,
+ initialPageParam: 0,
+ getNextPageParam: (lastPage, allPages, lastPageParam) => {
+ if (lastPage.length === 0) {
+ return undefined
+ }
+ return lastPageParam + 1
+ },
+ getPreviousPageParam: (firstPage, allPages, firstPageParam) => {
+ if (firstPageParam <= 1) {
+ return undefined
+ }
+ return firstPageParam - 1
+ },
+}))
+```
diff --git a/docs/zh-hans/framework/angular/guides/initial-query-data.md b/docs/zh-hans/framework/angular/guides/initial-query-data.md
new file mode 100644
index 00000000000..68a83d021e9
--- /dev/null
+++ b/docs/zh-hans/framework/angular/guides/initial-query-data.md
@@ -0,0 +1,140 @@
+---
+source-updated-at: '2024-01-26T03:31:25.000Z'
+translation-updated-at: '2025-05-06T05:04:23.076Z'
+id: initial-query-data
+title: 初始查询数据
+---
+
+在需要之前,有多种方式可以为查询提供初始数据到缓存中:
+
+- 声明式:
+ - 为查询提供 `initialData`,以便在缓存为空时预填充
+- 命令式:
+ - [使用 `queryClient.prefetchQuery` 预取数据](./prefetching.md)
+ - [使用 `queryClient.setQueryData` 手动将数据放入缓存](./prefetching.md)
+
+## 使用 `initialData` 预填充查询
+
+有时你可能已经在应用中拥有查询的初始数据,并可以直接提供给查询。这种情况下,你可以使用 `config.initialData` 选项来设置查询的初始数据,并跳过初始加载状态!
+
+> 重要提示:`initialData` 会被持久化到缓存中,因此不建议为此选项提供占位符、部分或不完整的数据,而应使用 `placeholderData`。
+
+```ts
+result = injectQuery(() => ({
+ queryKey: ['todos'],
+ queryFn: () => fetch('/todos'),
+ initialData: initialTodos,
+}))
+```
+
+### `staleTime` 和 `initialDataUpdatedAt`
+
+默认情况下,`initialData` 被视为完全新鲜的数据,就像刚刚获取的一样。这也意味着它会影响到 `staleTime` 选项的解释方式。
+
+- 如果为查询观察者配置了 `initialData` 且没有 `staleTime`(默认 `staleTime: 0`),查询会立即重新获取:
+
+```ts
+// 会立即显示 initialTodos,但在创建组件或服务的实例时也会立即重新获取 todos
+result = injectQuery(() => ({
+ queryKey: ['todos'],
+ queryFn: () => fetch('/todos'),
+ initialData: initialTodos,
+}))
+```
+
+- 如果为查询观察者配置了 `initialData` 且 `staleTime` 为 `1000` 毫秒,数据将在相同时间内被视为新鲜数据,就像刚刚从查询函数中获取的一样。
+
+```ts
+// 立即显示 initialTodos,但在 1000 毫秒后遇到另一个交互事件之前不会重新获取
+result = injectQuery(() => ({
+ queryKey: ['todos'],
+ queryFn: () => fetch('/todos'),
+ initialData: initialTodos,
+ staleTime: 1000,
+}))
+```
+
+- 那么如果 `initialData` 不是完全新鲜的怎么办?这引出了最后一种配置,它实际上是最准确的,并使用了一个名为 `initialDataUpdatedAt` 的选项。该选项允许你传递一个以毫秒为单位的 JS 时间戳,表示 `initialData` 上次更新的时间,例如 `Date.now()` 提供的时间戳。请注意,如果你有一个 Unix 时间戳,需要通过乘以 `1000` 将其转换为 JS 时间戳。
+
+```ts
+// 立即显示 initialTodos,但在 1 分钟后遇到另一个交互事件之前不会重新获取
+result = injectQuery(() => ({
+ queryKey: ['todos'],
+ queryFn: () => fetch('/todos'),
+ initialData: initialTodos,
+ staleTime: 60 * 1000, // 1 分钟
+ // 可能是 10 秒前或 10 分钟前
+ initialDataUpdatedAt: initialTodosUpdatedTimestamp, // 例如 1608412420052
+}))
+```
+
+该选项允许 `staleTime` 用于其原始目的,即确定数据需要多新鲜,同时也允许在初始化时重新获取数据(如果 `initialData` 比 `staleTime` 更旧)。在上面的示例中,我们的数据需要在 1 分钟内保持新鲜,并且我们可以提示查询 `initialData` 上次更新的时间,以便查询自行决定是否需要重新获取数据。
+
+> 如果你更愿意将数据视为 **预取数据**,建议使用 `prefetchQuery` 或 `fetchQuery` API 预先填充缓存,从而可以独立于 `initialData` 配置 `staleTime`。
+
+### 初始数据函数
+
+如果访问查询初始数据的过程很耗时,或者你不希望在每次服务或组件实例上执行该过程,可以将一个函数作为 `initialData` 的值传递。该函数仅在查询初始化时执行一次,从而节省宝贵的内存和/或 CPU:
+
+```ts
+result = injectQuery(() => ({
+ queryKey: ['todos'],
+ queryFn: () => fetch('/todos'),
+ initialData: () => getExpensiveTodos(),
+}))
+```
+
+### 从缓存中获取初始数据
+
+在某些情况下,你可以从另一个查询的缓存结果中为查询提供初始数据。一个很好的例子是从 todos 列表查询中搜索缓存的单个 todo 项数据,然后将其用作单个 todo 查询的初始数据:
+
+```ts
+result = injectQuery(() => ({
+ queryKey: ['todo', this.todoId()],
+ queryFn: () => fetch('/todos'),
+ initialData: () => {
+ // 使用 'todos' 查询中的一个 todo 作为此 todo 查询的初始数据
+ return this.queryClient
+ .getQueryData(['todos'])
+ ?.find((d) => d.id === this.todoId())
+ },
+}))
+```
+
+### 从缓存中获取初始数据并设置 `initialDataUpdatedAt`
+
+从缓存中获取初始数据意味着你用于查找初始数据的源查询可能已经过时。与其使用人为的 `staleTime` 来防止查询立即重新获取,建议将源查询的 `dataUpdatedAt` 传递给 `initialDataUpdatedAt`。这为查询实例提供了所需的所有信息,以确定是否以及何时需要重新获取查询,而不管是否提供了初始数据。
+
+```ts
+result = injectQuery(() => ({
+ queryKey: ['todos', this.todoId()],
+ queryFn: () => fetch(`/todos/${this.todoId()}`),
+ initialData: () =>
+ queryClient.getQueryData(['todos'])?.find((d) => d.id === this.todoId()),
+ initialDataUpdatedAt: () =>
+ queryClient.getQueryState(['todos'])?.dataUpdatedAt,
+}))
+```
+
+### 从缓存中条件性获取初始数据
+
+如果用于查找初始数据的源查询已经过时,你可能根本不想使用缓存的数据,而是直接从服务器获取。为了更容易做出这个决定,可以使用 `queryClient.getQueryState` 方法来获取有关源查询的更多信息,包括 `state.dataUpdatedAt` 时间戳,你可以用它来决定查询是否足够“新鲜”以满足你的需求:
+
+```ts
+result = injectQuery(() => ({
+ queryKey: ['todo', this.todoId()],
+ queryFn: () => fetch(`/todos/${this.todoId()}`),
+ initialData: () => {
+ // 获取查询状态
+ const state = queryClient.getQueryState(['todos'])
+
+ // 如果查询存在且数据不超过 10 秒...
+ if (state && Date.now() - state.dataUpdatedAt <= 10 * 1000) {
+ // 返回单个 todo
+ return state.data.find((d) => d.id === this.todoId())
+ }
+
+ // 否则返回 undefined,让它从硬加载状态获取!
+ },
+}))
+```
diff --git a/docs/zh-hans/framework/angular/guides/invalidations-from-mutations.md b/docs/zh-hans/framework/angular/guides/invalidations-from-mutations.md
new file mode 100644
index 00000000000..c08a9b68ad1
--- /dev/null
+++ b/docs/zh-hans/framework/angular/guides/invalidations-from-mutations.md
@@ -0,0 +1,42 @@
+---
+source-updated-at: '2025-01-03T15:54:42.000Z'
+translation-updated-at: '2025-05-06T05:03:17.566Z'
+id: invalidations-from-mutations
+title: 从变更中失效
+---
+
+## 变更触发的失效
+
+使查询失效只是成功的一半,而知道**何时**使其失效则是另一半。通常,当应用中的某个变更 (mutation) 成功执行时,应用中很可能存在相关的查询需要失效,并可能需要重新获取数据以反映该变更带来的新变化。
+
+例如,假设我们有一个用于发布新待办事项的变更:
+
+```ts
+mutation = injectMutation(() => ({
+ mutationFn: postTodo,
+}))
+```
+
+当 `postTodo` 变更成功执行时,我们很可能希望所有 `todos` 查询失效并可能重新获取,以显示新的待办事项。为此,你可以使用 `injectMutation` 的 `onSuccess` 选项和 `client` 的 `invalidateQueries` 函数:
+
+```ts
+import {
+ injectMutation,
+ QueryClient,
+} from '@tanstack/angular-query-experimental'
+
+export class TodosComponent {
+ queryClient = inject(QueryClient)
+
+ // 当此变更成功时,使所有带有 `todos` 或 `reminders` 查询键 (query key) 的查询失效
+ mutation = injectMutation(() => ({
+ mutationFn: addTodo,
+ onSuccess: () => {
+ this.queryClient.invalidateQueries({ queryKey: ['todos'] })
+ this.queryClient.invalidateQueries({ queryKey: ['reminders'] })
+ },
+ }))
+}
+```
+
+你可以利用 [`injectMutation` 函数](./mutations.md) 中提供的任何回调来设置失效逻辑。
diff --git a/docs/zh-hans/framework/angular/guides/mutation-options.md b/docs/zh-hans/framework/angular/guides/mutation-options.md
new file mode 100644
index 00000000000..fd7cfb9fef2
--- /dev/null
+++ b/docs/zh-hans/framework/angular/guides/mutation-options.md
@@ -0,0 +1,25 @@
+---
+source-updated-at: '2024-11-20T12:58:00.000Z'
+translation-updated-at: '2025-05-06T05:03:00.167Z'
+id: query-options
+title: 变更选项
+---
+
+在多个地方共享变更选项 (mutation options) 的最佳方式之一,就是使用 `mutationOptions` 辅助函数。在运行时,这个辅助函数会原样返回你传入的内容,但[配合 TypeScript](../../typescript#typing-query-options) 使用时能带来诸多优势。你可以在一个地方定义变更操作的所有可能选项,同时还能获得完整的类型推断和类型安全。
+
+```ts
+export class QueriesService {
+ private http = inject(HttpClient)
+
+ updatePost(id: number) {
+ return mutationOptions({
+ mutationFn: (post: Post) => Promise.resolve(post),
+ mutationKey: ['updatePost', id],
+ onSuccess: (newPost) => {
+ // ^? newPost: Post
+ this.queryClient.setQueryData(['posts', id], newPost)
+ },
+ })
+ }
+}
+```
diff --git a/docs/zh-hans/framework/angular/guides/mutations.md b/docs/zh-hans/framework/angular/guides/mutations.md
new file mode 100644
index 00000000000..2e18443f0d2
--- /dev/null
+++ b/docs/zh-hans/framework/angular/guides/mutations.md
@@ -0,0 +1,300 @@
+---
+source-updated-at: '2024-07-19T09:36:35.000Z'
+translation-updated-at: '2025-05-06T05:02:49.197Z'
+id: mutations
+title: 变更
+---
+
+与查询 (query) 不同,变更 (mutation) 通常用于创建/更新/删除数据或执行服务端副作用。为此,TanStack Query 导出了 `injectMutation` 函数。
+
+以下是一个向服务器添加新待办事项的变更示例:
+
+```angular-ts
+@Component({
+ template: `
+
+ @if (mutation.isPending()) {
+
添加待办事项中...
+ } @else if (mutation.isError()) {
+
发生错误:{{ mutation.error()?.message }}
+ } @else if (mutation.isSuccess()) {
+
待办事项已添加!
+ }
+
创建待办事项
+
+ `,
+})
+export class TodosComponent {
+ todoService = inject(TodoService)
+ mutation = injectMutation(() => ({
+ mutationFn: (todoId: number) =>
+ lastValueFrom(this.todoService.create(todoId)),
+ }))
+}
+```
+
+变更在任何时刻只能处于以下状态之一:
+
+- `isIdle` 或 `status === 'idle'` - 变更当前处于空闲或重置状态
+- `isPending` 或 `status === 'pending'` - 变更正在执行中
+- `isError` 或 `status === 'error'` - 变更遇到错误
+- `isSuccess` 或 `status === 'success'` - 变更成功完成且数据可用
+
+除这些主要状态外,根据变更状态还可获取更多信息:
+
+- `error` - 如果变更处于 `error` 状态,可通过 `error` 属性获取错误信息
+- `data` - 如果变更处于 `success` 状态,可通过 `data` 属性获取返回数据
+
+在上例中,您还可以看到通过调用 `mutate` 函数并传入**单个变量或对象**来向变更函数传递参数。
+
+仅使用变量时,变更并不特殊,但当与 `onSuccess` 选项、[Query Client 的 `invalidateQueries` 方法](../../../reference/QueryClient.md#queryclientinvalidatequeries) 以及 [Query Client 的 `setQueryData` 方法](../../../reference/QueryClient.md#queryclientsetquerydata) 结合使用时,变更将成为非常强大的工具。
+
+## 重置变更状态
+
+有时您需要清除变更请求的 `error` 或 `data`。为此,可以使用 `reset` 函数处理:
+
+```angular-ts
+@Component({
+ standalone: true,
+ selector: 'todo-item',
+ imports: [ReactiveFormsModule],
+ template: `
+
+ `,
+})
+export class TodosComponent {
+ mutation = injectMutation(() => ({
+ mutationFn: createTodo,
+ }))
+
+ fb = inject(NonNullableFormBuilder)
+
+ todoForm = this.fb.group({
+ title: this.fb.control('', {
+ validators: [Validators.required],
+ }),
+ })
+
+ title = toSignal(this.todoForm.controls.title.valueChanges, {
+ initialValue: '',
+ })
+
+ onCreateTodo = () => {
+ this.mutation.mutate(this.title())
+ }
+}
+```
+
+## 变更副作用
+
+`injectMutation` 提供了一些辅助选项,允许在变更生命周期的任何阶段快速实现副作用。这些选项对于[变更后使查询失效并重新获取](./invalidations-from-mutations.md)甚至[乐观更新](./optimistic-updates.md)非常有用。
+
+```ts
+mutation = injectMutation(() => ({
+ mutationFn: addTodo,
+ onMutate: (variables) => {
+ // 变更即将执行!
+ // 可选返回包含数据的上下文,用于回滚等场景
+ return { id: 1 }
+ },
+ onError: (error, variables, context) => {
+ // 发生错误!
+ console.log(`正在回滚 ID 为 ${context.id} 的乐观更新`)
+ },
+ onSuccess: (data, variables, context) => {
+ // 成功!
+ },
+ onSettled: (data, error, variables, context) => {
+ // 无论成功或失败都会执行!
+ },
+}))
+```
+
+在任何回调函数中返回 Promise 时,会先等待该 Promise 完成再执行下一个回调:
+
+```ts
+mutation = injectMutation(() => ({
+ mutationFn: addTodo,
+ onSuccess: async () => {
+ console.log('我先执行!')
+ },
+ onSettled: async () => {
+ console.log('我第二个执行!')
+ },
+}))
+```
+
+您可能希望在调用 `mutate` 时**触发额外的回调**,而不仅限于 `injectMutation` 定义的回调。这可用于触发组件特定的副作用。为此,您可以在变更变量后向 `mutate` 函数提供相同的回调选项。支持的选项包括:`onSuccess`、`onError` 和 `onSettled`。请注意,如果组件在变更完成前被销毁,这些额外回调将不会执行。
+
+```ts
+mutation = injectMutation(() => ({
+ mutationFn: addTodo,
+ onSuccess: (data, variables, context) => {
+ // 我会第一个触发
+ },
+ onError: (error, variables, context) => {
+ // 我会第一个触发
+ },
+ onSettled: (data, error, variables, context) => {
+ // 我会第一个触发
+ },
+}))
+
+mutation.mutate(todo, {
+ onSuccess: (data, variables, context) => {
+ // 我会第二个触发!
+ },
+ onError: (error, variables, context) => {
+ // 我会第二个触发!
+ },
+ onSettled: (data, error, variables, context) => {
+ // 我会第二个触发!
+ },
+})
+```
+
+### 连续变更
+
+处理连续变更时,`onSuccess`、`onError` 和 `onSettled` 回调的行为略有不同。当传递给 `mutate` 函数时,它们只会在组件仍处于活动状态时触发一次。这是因为每次调用 `mutate` 函数时,变更观察器都会被移除并重新订阅。相反,`injectMutation` 的处理程序会为每个 `mutate` 调用执行。
+
+> 请注意,传递给 `injectMutation` 的 `mutationFn` 很可能是异步的。在这种情况下,变更完成的顺序可能与 `mutate` 函数调用的顺序不同。
+
+```ts
+export class Example {
+ mutation = injectMutation(() => ({
+ mutationFn: addTodo,
+ onSuccess: (data, variables, context) => {
+ // 会被调用 3 次
+ },
+ }))
+
+ doMutations() {
+ ;['Todo 1', 'Todo 2', 'Todo 3'].forEach((todo) => {
+ this.mutation.mutate(todo, {
+ onSuccess: (data, variables, context) => {
+ // 只会执行一次,针对最后一个变更 (Todo 3),
+ // 无论哪个变更先完成
+ },
+ })
+ })
+ }
+}
+```
+
+## Promise
+
+使用 `mutateAsync` 替代 `mutate` 可以获取一个 Promise,该 Promise 在成功时解析或在出错时抛出异常。例如,这可用于组合副作用。
+
+```ts
+mutation = injectMutation(() => ({ mutationFn: addTodo }))
+
+try {
+ const todo = await mutation.mutateAsync(todo)
+ console.log(todo)
+} catch (error) {
+ console.error(error)
+} finally {
+ console.log('完成')
+}
+```
+
+## 重试
+
+默认情况下,TanStack Query 不会在出错时重试变更,但可以通过 `retry` 选项启用:
+
+```ts
+mutation = injectMutation(() => ({
+ mutationFn: addTodo,
+ retry: 3,
+}))
+```
+
+如果因设备离线导致变更失败,它们会在设备重新连接时按相同顺序重试。
+
+## 持久化变更
+
+如果需要,可以将变更持久化到存储中,并在以后恢复。这可以通过水合 (hydration) 函数实现:
+
+```ts
+const queryClient = new QueryClient()
+
+// 定义 "addTodo" 变更
+queryClient.setMutationDefaults(['addTodo'], {
+ mutationFn: addTodo,
+ onMutate: async (variables) => {
+ // 取消当前待办事项列表的查询
+ await queryClient.cancelQueries({ queryKey: ['todos'] })
+
+ // 创建乐观待办事项
+ const optimisticTodo = { id: uuid(), title: variables.title }
+
+ // 将乐观待办事项添加到列表
+ queryClient.setQueryData(['todos'], (old) => [...old, optimisticTodo])
+
+ // 返回包含乐观待办事项的上下文
+ return { optimisticTodo }
+ },
+ onSuccess: (result, variables, context) => {
+ // 用结果替换列表中的乐观待办事项
+ queryClient.setQueryData(['todos'], (old) =>
+ old.map((todo) =>
+ todo.id === context.optimisticTodo.id ? result : todo,
+ ),
+ )
+ },
+ onError: (error, variables, context) => {
+ // 从列表中移除乐观待办事项
+ queryClient.setQueryData(['todos'], (old) =>
+ old.filter((todo) => todo.id !== context.optimisticTodo.id),
+ )
+ },
+ retry: 3,
+})
+
+class someComponent {
+ // 在组件中启动变更:
+ mutation = injectMutation(() => ({ mutationKey: ['addTodo'] }))
+
+ someMethod() {
+ mutation.mutate({ title: '标题' })
+ }
+}
+
+// 如果变更因设备离线等原因被暂停,
+// 可以在应用退出时将暂停的变更脱水:
+const state = dehydrate(queryClient)
+
+// 然后在应用启动时重新水合:
+hydrate(queryClient, state)
+
+// 恢复暂停的变更:
+queryClient.resumePausedMutations()
+```
+
+### 持久化离线变更
+
+如果使用 [persistQueryClient 插件](../plugins/persistQueryClient.md) 持久化离线变更,除非提供默认的变更函数,否则在页面重新加载时无法恢复变更。
+
+这是一个技术限制。当持久化到外部存储时,只能持久化变更的状态,因为函数无法被序列化。水合后,触发变更的组件可能尚未初始化,因此调用 `resumePausedMutations` 可能会导致错误:`未找到 mutationFn`。
+
+我们还提供了一个全面的[离线示例](../examples/react/offline),涵盖查询和变更。
+
+## 变更作用域
+
+默认情况下,所有变更并行运行——即使多次调用同一变更的 `.mutate()`。可以通过带有 `id` 的 `scope` 来避免这种情况。具有相同 `scope.id` 的所有变更将串行运行,这意味着当它们被触发时,如果该作用域已有变更在进行中,它们将以 `isPaused: true` 状态启动。它们会被放入队列,并在轮到它们时自动恢复。
+
+```tsx
+const mutation = injectMutation({
+ mutationFn: addTodo,
+ scope: {
+ id: 'todo',
+ },
+})
+```
diff --git a/docs/zh-hans/framework/angular/guides/network-mode.md b/docs/zh-hans/framework/angular/guides/network-mode.md
new file mode 100644
index 00000000000..d7fcdd93247
--- /dev/null
+++ b/docs/zh-hans/framework/angular/guides/network-mode.md
@@ -0,0 +1,7 @@
+---
+source-updated-at: '2024-01-26T03:31:25.000Z'
+translation-updated-at: '2025-05-06T04:54:02.024Z'
+id: network-mode
+title: Network Mode
+ref: docs/zh-hans/framework/react/guides/network-mode.md
+---
diff --git a/docs/zh-hans/framework/angular/guides/optimistic-updates.md b/docs/zh-hans/framework/angular/guides/optimistic-updates.md
new file mode 100644
index 00000000000..030d9895a5a
--- /dev/null
+++ b/docs/zh-hans/framework/angular/guides/optimistic-updates.md
@@ -0,0 +1,173 @@
+---
+source-updated-at: '2024-11-19T18:32:49.000Z'
+translation-updated-at: '2025-05-06T05:00:55.440Z'
+id: optimistic-updates
+title: 乐观更新
+---
+
+Angular Query 提供了两种在变更操作完成前乐观更新 UI 的方式。您既可以使用 `onMutate` 选项直接更新缓存,也可以利用 `injectMutation` 返回的 `variables` 从结果中更新 UI。
+
+## 通过 UI 更新
+
+这是更简单的实现方式,因为它不直接与缓存交互。
+
+```ts
+addTodo = injectMutation(() => ({
+ mutationFn: (newTodo: string) => axios.post('/api/data', { text: newTodo }),
+ // 确保返回查询失效的 Promise
+ // 使变更保持 `pending` 状态直到重新获取完成
+ onSettled: async () => {
+ return await queryClient.invalidateQueries({ queryKey: ['todos'] })
+ },
+}))
+```
+
+之后您可以通过 `addTodo.variables` 访问新增的待办事项。在渲染查询的 UI 列表中,当变更处于 `isPending` 状态时,您可以向列表追加一个临时项:
+
+```angular-ts
+@Component({
+ template: `
+ @for (todo of todos.data(); track todo.id) {
+ {{ todo.title }}
+ }
+ @if (addTodo.isPending()) {
+ {{ addTodo.variables() }}
+ }
+ `,
+})
+class TodosComponent {}
+```
+
+我们通过不同的 `opacity` 样式渲染临时项,直到变更完成。成功后该项会自动消失。如果重新获取成功,该项会作为"正常条目"出现在列表中。
+
+若变更出错,该项同样会消失。但如果我们希望保留显示,可以通过检查变更的 `isError` 状态实现。出错时 `variables` 不会被清除,因此我们仍可访问它们,甚至可以显示重试按钮:
+
+```angular-ts
+@Component({
+ template: `
+ @if (addTodo.isError()) {
+
+ {{ addTodo.variables() }}
+ Retry
+
+ }
+ `,
+})
+class TodosComponent {}
+```
+
+### 当变更与查询不在同一组件时
+
+这种方式在变更与查询同处一个组件时效果最佳。但您也可以通过专用的 `injectMutationState` 函数访问其他组件中的所有变更,建议配合 `mutationKey` 使用:
+
+```ts
+// 在应用某处
+addTodo = injectMutation(() => ({
+ mutationFn: (newTodo: string) => axios.post('/api/data', { text: newTodo }),
+ onSettled: () => queryClient.invalidateQueries({ queryKey: ['todos'] }),
+ mutationKey: ['addTodo'],
+}))
+
+// 在其他位置访问变量
+mutationState = injectMutationState(() => ({
+ filters: { mutationKey: ['addTodo'], status: 'pending' },
+ select: (mutation) => mutation.state.variables,
+}))
+```
+
+由于可能同时存在多个变更,`variables` 会是一个数组。如果需要唯一键,我们还可以选择 `mutation.state.submittedAt`,这将使并发乐观更新变得轻而易举。
+
+## 通过缓存更新
+
+在执行变更前乐观更新状态时,存在操作失败的可能性。多数情况下只需触发乐观查询的重新获取即可恢复至真实服务端状态。但某些情况下重新获取可能失效,此时您可以选择回滚更新。
+
+通过 `injectMutation` 的 `onMutate` 处理程序,您可以返回一个值,该值将作为最后一个参数传递给 `onError` 和 `onSettled` 处理程序。通常传递回滚函数最为实用。
+
+### 添加新待办事项时更新列表
+
+```ts
+queryClient = inject(QueryClient)
+
+updateTodo = injectMutation(() => ({
+ mutationFn: updateTodo,
+ // 当调用 mutate 时:
+ onMutate: async (newTodo) => {
+ // 取消所有待处理的查询
+ // (防止覆盖我们的乐观更新)
+ await this.queryClient.cancelQueries({ queryKey: ['todos'] })
+
+ // 保存当前值的快照
+ const previousTodos = client.getQueryData(['todos'])
+
+ // 乐观更新为新值
+ this.queryClient.setQueryData(['todos'], (old) => [...old, newTodo])
+
+ // 返回包含快照值的上下文对象
+ return { previousTodos }
+ },
+ // 如果变更失败
+ // 使用 onMutate 返回的上下文进行回滚
+ onError: (err, newTodo, context) => {
+ client.setQueryData(['todos'], context.previousTodos)
+ },
+ // 无论成功失败都重新获取:
+ onSettled: () => {
+ this.queryClient.invalidateQueries({ queryKey: ['todos'] })
+ },
+}))
+```
+
+### 更新单个待办事项
+
+```ts
+queryClient = inject(QueryClient)
+
+updateTodo = injectMutation(() => ({
+ mutationFn: updateTodo,
+ // 当调用 mutate 时:
+ onMutate: async (newTodo) => {
+ // 取消相关查询
+ await this.queryClient.cancelQueries({ queryKey: ['todos', newTodo.id] })
+
+ // 保存当前值的快照
+ const previousTodo = this.queryClient.getQueryData(['todos', newTodo.id])
+
+ // 乐观更新
+ this.queryClient.setQueryData(['todos', newTodo.id], newTodo)
+
+ // 返回包含新旧值的上下文
+ return { previousTodo, newTodo }
+ },
+ // 出错时使用上文返回的上下文
+ onError: (err, newTodo, context) => {
+ this.queryClient.setQueryData(
+ ['todos', context.newTodo.id],
+ context.previousTodo,
+ )
+ },
+ // 总是重新获取:
+ onSettled: (newTodo) => {
+ this.queryClient.invalidateQueries({ queryKey: ['todos', newTodo.id] })
+ },
+}))
+```
+
+您也可以用 `onSettled` 替代单独的 `onError` 和 `onSuccess` 处理程序:
+
+```ts
+injectMutation({
+ mutationFn: updateTodo,
+ // ...
+ onSettled: (newTodo, error, variables, context) => {
+ if (error) {
+ // 错误处理
+ }
+ },
+})
+```
+
+## 方案选择建议
+
+如果只需在单一位置显示乐观结果,使用 `variables` 直接更新 UI 的方式代码更少且更易维护。例如您完全不需要处理回滚逻辑。
+
+但如果您需要在屏幕上多个位置同步更新状态,直接操作缓存的方式会自动为您处理这些关联更新。
diff --git a/docs/zh-hans/framework/angular/guides/paginated-queries.md b/docs/zh-hans/framework/angular/guides/paginated-queries.md
new file mode 100644
index 00000000000..14f627556f7
--- /dev/null
+++ b/docs/zh-hans/framework/angular/guides/paginated-queries.md
@@ -0,0 +1,107 @@
+---
+source-updated-at: '2024-11-14T21:48:46.000Z'
+translation-updated-at: '2025-05-06T04:59:52.176Z'
+id: paginated-queries
+title: 分页查询
+---
+
+分页渲染数据是一种非常常见的 UI 模式,在 TanStack Query 中,只需将页码信息包含在查询键 (query key) 中即可实现:
+
+```ts
+const result = injectQuery(() => ({
+ queryKey: ['projects', page()],
+ queryFn: fetchProjects,
+}))
+```
+
+但运行这个简单示例时,你可能会注意到一个奇怪的现象:
+
+**UI 会在 `success` 和 `pending` 状态之间反复切换,因为每个新页面都被视为一个全新的查询。**
+
+这种体验并不理想,遗憾的是许多工具至今仍坚持这种工作方式。但 TanStack Query 不同!你可能已经猜到,TanStack Query 提供了一个名为 `placeholderData` 的强大功能来解决这个问题。
+
+## 使用 `placeholderData` 优化分页查询
+
+考虑以下场景:我们希望逐步增加查询的页码索引 (pageIndex) 或游标 (cursor)。如果使用 `injectQuery`,**技术上虽然可行**,但 UI 会随着每个页面创建和销毁不同查询而在 `success` 和 `pending` 状态间跳转。通过将 `placeholderData` 设为 `(previousData) => previousData` 或使用 TanStack Query 导出的 `keepPreviousData` 函数,我们可以获得以下特性:
+
+- **即使查询键已变更,在请求新数据期间仍能访问上次成功获取的数据**
+- 当新数据到达时,会无缝切换显示新数据
+- 可通过 `isPlaceholderData` 判断当前查询提供的数据类型
+
+```angular-ts
+@Component({
+ selector: 'pagination-example',
+ template: `
+
+
+ 本示例中,当获取下一页时,当前页数据仍保持可见。下一页按钮和相关功能会在获取到下一页游标前禁用。每页数据都会作为普通查询缓存,因此返回上一页时会立即显示,同时后台会自动重新获取最新数据。
+
+ @if (query.status() === 'pending') {
+
加载中...
+ } @else if (query.status() === 'error') {
+
错误: {{ query.error().message }}
+ } @else {
+
+
+
+ @for (project of query.data().projects; track project.id) {
+
{{ project.name }}
+ }
+
+ }
+
+
当前页: {{ page() + 1 }}
+
+ 上一页
+
+
+ 下一页
+
+
+
+
+ @if (query.isFetching()) {
+
加载中...
+ }
+
+ `,
+})
+export class PaginationExampleComponent {
+ page = signal(0)
+ queryClient = inject(QueryClient)
+
+ query = injectQuery(() => ({
+ queryKey: ['projects', this.page()],
+ queryFn: () => lastValueFrom(fetchProjects(this.page())),
+ placeholderData: keepPreviousData,
+ staleTime: 5000,
+ }))
+
+ constructor() {
+ effect(() => {
+ // 预取下一页!
+ if (!this.query.isPlaceholderData() && this.query.data()?.hasMore) {
+ this.#queryClient.prefetchQuery({
+ queryKey: ['projects', this.page() + 1],
+ queryFn: () => lastValueFrom(fetchProjects(this.page() + 1)),
+ })
+ }
+ })
+ }
+
+ previousPage() {
+ this.page.update((old) => Math.max(old - 1, 0))
+ }
+
+ nextPage() {
+ this.page.update((old) => (this.query.data()?.hasMore ? old + 1 : old))
+ }
+}
+```
+
+## 使用 `placeholderData` 实现无限查询结果延迟加载
+
+虽然不太常见,但 `placeholderData` 选项与 `injectInfiniteQuery` 函数也能完美配合,让你可以在无限查询键随时间变化时,仍让用户无缝查看缓存数据。
diff --git a/docs/zh-hans/framework/angular/guides/parallel-queries.md b/docs/zh-hans/framework/angular/guides/parallel-queries.md
new file mode 100644
index 00000000000..e1031a17cc1
--- /dev/null
+++ b/docs/zh-hans/framework/angular/guides/parallel-queries.md
@@ -0,0 +1,46 @@
+---
+source-updated-at: '2024-01-26T03:31:25.000Z'
+translation-updated-at: '2025-05-06T04:59:05.811Z'
+id: parallel-queries
+title: 并行查询
+---
+
+"并行 (Parallel)" 查询是指同时执行多个查询,以最大化数据获取的并发性。
+
+## 手动并行查询
+
+当并行查询的数量固定时,使用并行查询**无需额外操作**。只需并排使用任意数量的 TanStack Query 提供的 `injectQuery` 和 `injectInfiniteQuery` 函数即可!
+
+```ts
+export class AppComponent {
+ // 以下查询将并行执行
+ usersQuery = injectQuery(() => ({ queryKey: ['users'], queryFn: fetchUsers }))
+ teamsQuery = injectQuery(() => ({ queryKey: ['teams'], queryFn: fetchTeams }))
+ projectsQuery = injectQuery(() => ({
+ queryKey: ['projects'],
+ queryFn: fetchProjects,
+ }))
+}
+```
+
+## 使用 `injectQueries` 实现动态并行查询
+
+TanStack Query 提供了 `injectQueries` 方法,可用于动态执行任意数量的并行查询。
+
+`injectQueries` 接收一个包含 **queries 键**的**配置对象**,该键的值是**查询对象数组**。该方法会返回一个**查询结果数组**:
+
+```ts
+export class AppComponent {
+ users = signal>([])
+
+ // 请注意 injectQueries 正在开发中,以下代码暂不可用
+ userQueries = injectQueries(() => ({
+ queries: users().map((user) => {
+ return {
+ queryKey: ['user', user.id],
+ queryFn: () => fetchUserById(user.id),
+ }
+ }),
+ }))
+}
+```
diff --git a/docs/zh-hans/framework/angular/guides/placeholder-query-data.md b/docs/zh-hans/framework/angular/guides/placeholder-query-data.md
new file mode 100644
index 00000000000..1f53b3b3b76
--- /dev/null
+++ b/docs/zh-hans/framework/angular/guides/placeholder-query-data.md
@@ -0,0 +1,75 @@
+---
+source-updated-at: '2024-11-14T21:48:46.000Z'
+translation-updated-at: '2025-05-06T04:58:48.269Z'
+id: placeholder-query-data
+title: 占位查询数据
+---
+
+## 什么是占位数据?
+
+占位数据允许查询表现得好像已经拥有数据,类似于 `initialData` 选项,但**这些数据不会被持久化到缓存中**。这在以下场景中非常有用:当实际数据还在后台获取时,你已经拥有足够的局部(或模拟)数据来成功渲染查询。
+
+> 示例:一篇博客文章的查询可以从父级博客列表拉取仅包含标题和文章片段缩略的"预览"数据。你可能不希望将这些局部数据持久化到独立查询的结果中,但它能帮助在完整数据获取完成前尽可能快地展示内容布局。
+
+在需要实际数据前,有几种方式可以为查询提供占位数据到缓存:
+
+- 声明式:
+ - 为查询提供 `placeholderData` 以便在缓存为空时预填充
+- 命令式:
+ - [使用 `queryClient` 和 `placeholderData` 选项预取或获取数据](./prefetching.md)
+
+当我们使用 `placeholderData` 时,查询不会处于 `pending` 状态——它会直接从 `success` 状态开始,因为已有可展示的 `data`(即使只是"占位"数据)。为了与"真实"数据区分,查询结果中还会将 `isPlaceholderData` 标志设为 `true`。
+
+## 作为值的占位数据
+
+```ts
+class TodosComponent {
+ result = injectQuery(() => ({
+ queryKey: ['todos'],
+ queryFn: () => fetch('/todos'),
+ placeholderData: placeholderTodos,
+ }))
+}
+```
+
+## 作为函数的占位数据
+
+`placeholderData` 也可以是一个函数,通过它你能访问"先前"成功查询的数据和元信息。这在需要将一个查询的数据作为另一个查询的占位数据时非常实用。当 QueryKey 变化时(例如从 `['todos', 1]` 变为 `['todos', 2]`),我们可以继续显示"旧"数据,避免在数据从一个查询过渡到下一个时展示加载动画。更多信息请参阅[分页查询](./paginated-queries.md)。
+
+```ts
+class TodosComponent {
+ result = injectQuery(() => ({
+ queryKey: ['todos', id()],
+ queryFn: () => fetch(`/todos/${id}`),
+ placeholderData: (previousData, previousQuery) => previousData,
+ }))
+}
+```
+
+### 从缓存获取占位数据
+
+某些情况下,你可以从其他查询的缓存结果中提供占位数据。一个典型场景是:从博客文章列表查询的缓存数据中搜索文章的预览版本,然后将其用作独立文章查询的占位数据:
+
+```ts
+export class BlogPostComponent {
+ // 在 Angular 支持基于信号的输入前,我们需要手动设置信号
+ @Input({ required: true, alias: 'postId' })
+ set _postId(value: number) {
+ this.postId.set(value)
+ }
+ postId = signal(0)
+ queryClient = inject(QueryClient)
+
+ result = injectQuery(() => ({
+ queryKey: ['blogPost', this.postId()],
+ queryFn: () => fetch(`/blogPosts/${this.postId()}`),
+ placeholderData: () => {
+ // 使用 'blogPosts' 查询中的精简/预览版博客文章
+ // 作为当前博客文章查询的占位数据
+ return queryClient
+ .getQueryData(['blogPosts'])
+ ?.find((d) => d.id === this.postId())
+ },
+ }))
+}
+```
diff --git a/docs/zh-hans/framework/angular/guides/queries.md b/docs/zh-hans/framework/angular/guides/queries.md
new file mode 100644
index 00000000000..47e6e865b97
--- /dev/null
+++ b/docs/zh-hans/framework/angular/guides/queries.md
@@ -0,0 +1,126 @@
+---
+source-updated-at: '2025-03-01T21:43:55.000Z'
+translation-updated-at: '2025-05-06T04:58:12.365Z'
+id: queries
+title: 查询
+---
+
+## 查询基础
+
+查询是与**唯一键**绑定的、对异步数据源的声明式依赖。查询可用于任何基于 Promise 的方法(包括 GET 和 POST 方法)从服务器获取数据。如果您的方法会修改服务器上的数据,建议改用[变更](./mutations.md)。
+
+要在组件或服务中订阅查询,调用 `injectQuery` 时至少需要提供:
+
+- **查询的唯一键**
+- 返回 Promise 或 Observable 的函数,该函数应:
+ - 解析数据,或
+ - 抛出错误
+
+```ts
+import { injectQuery } from '@tanstack/angular-query-experimental'
+
+export class TodosComponent {
+ info = injectQuery(() => ({ queryKey: ['todos'], queryFn: fetchTodoList }))
+}
+```
+
+您提供的**唯一键**将在内部用于重新获取、缓存和在应用程序中共享查询。
+
+`injectQuery` 返回的查询结果包含您需要用于模板渲染或任何其他数据操作的所有查询信息:
+
+```ts
+result = injectQuery(() => ({ queryKey: ['todos'], queryFn: fetchTodoList }))
+```
+
+`result` 对象包含几个非常重要的状态,您需要了解这些状态才能高效使用。查询在任何时刻只能处于以下状态之一:
+
+- `isPending` 或 `status === 'pending'` - 查询尚无数据
+- `isError` 或 `status === 'error'` - 查询遇到错误
+- `isSuccess` 或 `status === 'success'` - 查询成功且数据可用
+
+除了这些主要状态外,根据查询状态还可获取更多信息:
+
+- `error` - 如果查询处于 `isError` 状态,可通过 `error` 属性获取错误信息。
+- `data` - 如果查询处于 `isSuccess` 状态,可通过 `data` 属性获取数据。
+- `isFetching` - 在任何状态下,如果查询正在获取数据(包括后台重新获取),`isFetching` 将为 `true`。
+
+对于**大多数**查询,通常只需检查 `isPending` 状态,然后是 `isError` 状态,最后可以假设数据可用并渲染成功状态:
+
+```angular-ts
+@Component({
+ selector: 'todos',
+ standalone: true,
+ template: `
+ @if (todos.isPending()) {
+ Loading...
+ } @else if (todos.isError()) {
+ Error: {{ todos.error()?.message }}
+ } @else {
+
+ @for (todo of todos.data(); track todo.id) {
+ {{ todo.title }}
+ } @empty {
+ No todos found
+ }
+ }
+ `,
+})
+export class PostsComponent {
+ todos = injectQuery(() => ({
+ queryKey: ['todos'],
+ queryFn: fetchTodoList,
+ }))
+}
+```
+
+如果不喜欢布尔值,也可以始终使用 `status` 状态:
+
+```angular-ts
+@Component({
+ selector: 'todos',
+ standalone: true,
+ template: `
+ @switch (todos.status()) {
+ @case ('pending') {
+ Loading...
+ }
+ @case ('error') {
+ Error: {{ todos.error()?.message }}
+ }
+
+ @default {
+
+ @for (todo of todos.data(); track todo.id) {
+ {{ todo.title }}
+ } @empty {
+ No todos found
+ }
+
+ }
+ }
+ `,
+})
+class TodosComponent {}
+```
+
+如果您在访问 `data` 之前检查了 `pending` 和 `error`,TypeScript 也会正确缩小 `data` 的类型范围。
+
+### 获取状态 (FetchStatus)
+
+除了 `status` 字段外,您还会获得一个额外的 `fetchStatus` 属性,其可选值为:
+
+- `fetchStatus === 'fetching'` - 查询正在获取数据。
+- `fetchStatus === 'paused'` - 查询希望获取数据,但被暂停。更多信息请参阅[网络模式](./network-mode.md)指南。
+- `fetchStatus === 'idle'` - 查询当前未进行任何操作。
+
+### 为什么有两种不同的状态?
+
+后台重新获取和“陈旧数据优先重新验证”逻辑使得 `status` 和 `fetchStatus` 的所有组合都可能出现。例如:
+
+- 处于 `success` 状态的查询通常处于 `idle` 获取状态,但如果正在进行后台重新获取,也可能处于 `fetching` 状态。
+- 刚挂载且没有数据的查询通常处于 `pending` 状态和 `fetching` 获取状态,但如果无网络连接,也可能处于 `paused` 状态。
+
+因此请记住,查询可能处于 `pending` 状态而实际上并未获取数据。作为经验法则:
+
+- `status` 提供关于 `data` 的信息:我们是否有数据?
+- `fetchStatus` 提供关于 `queryFn` 的信息:它是否正在运行?
diff --git a/docs/zh-hans/framework/angular/guides/query-cancellation.md b/docs/zh-hans/framework/angular/guides/query-cancellation.md
new file mode 100644
index 00000000000..d5429552935
--- /dev/null
+++ b/docs/zh-hans/framework/angular/guides/query-cancellation.md
@@ -0,0 +1,108 @@
+---
+source-updated-at: '2024-11-14T21:48:46.000Z'
+translation-updated-at: '2025-05-06T04:57:20.291Z'
+id: query-cancellation
+title: 查询取消
+---
+
+TanStack Query 为每个查询函数提供了一个 [`AbortSignal` 实例](https://developer.mozilla.org/docs/Web/API/AbortSignal)。当查询过期或变为非活跃状态时,该 `signal` 会被中止。这意味着所有查询均可取消,并且您可以根据需要在查询函数内部响应取消操作。最棒的是,它允许您继续使用普通的 async/await 语法,同时获得自动取消的所有优势。
+
+## 默认行为
+
+默认情况下,在 Promise 解析之前卸载或不再使用的查询*不会*被取消。这意味着 Promise 解析后,结果数据仍会保留在缓存中。这对于已经开始接收查询但随后在完成前卸载组件的情况非常有用。如果您再次挂载组件且查询尚未被垃圾回收,数据将仍然可用。
+
+然而,如果您使用了 `AbortSignal`,Promise 将被取消(例如中止 fetch 请求),因此查询也必须被取消。取消查询将导致其状态*回退*到之前的状态。
+
+## 使用 `HttpClient`
+
+```ts
+import { HttpClient } from '@angular/common/http'
+import { injectQuery } from '@tanstack/angular-query-experimental'
+
+postQuery = injectQuery(() => ({
+ enabled: this.postId() > 0,
+ queryKey: ['post', this.postId()],
+ queryFn: async (context): Promise => {
+ const abort$ = fromEvent(context.signal, 'abort')
+ return lastValueFrom(this.getPost$(this.postId()).pipe(takeUntil(abort$))
+ },
+}))
+```
+
+## 使用 `fetch`
+
+[//]: # 'Example2'
+
+```ts
+query = injectQuery(() => ({
+ queryKey: ['todos'],
+ queryFn: async ({ signal }) => {
+ const todosResponse = await fetch('/todos', {
+ // 将 signal 传递给 fetch
+ signal,
+ })
+ const todos = await todosResponse.json()
+
+ const todoDetails = todos.map(async ({ details }) => {
+ const response = await fetch(details, {
+ // 或者传递给多个请求
+ signal,
+ })
+ return response.json()
+ })
+
+ return Promise.all(todoDetails)
+ },
+}))
+```
+
+[//]: # 'Example2'
+
+## 使用 `axios`
+
+[//]: # 'Example3'
+
+```tsx
+import axios from 'axios'
+
+const query = injectQuery(() => ({
+ queryKey: ['todos'],
+ queryFn: ({ signal }) =>
+ axios.get('/todos', {
+ // 将 signal 传递给 `axios`
+ signal,
+ }),
+}))
+```
+
+[//]: # 'Example3'
+
+## 手动取消
+
+您可能需要手动取消查询。例如,如果请求需要很长时间才能完成,您可以允许用户点击取消按钮来停止请求。为此,只需调用 `queryClient.cancelQueries({ queryKey })`,这将取消查询并将其状态回退到之前的状态。如果您已经使用了传递给查询函数的 `signal`,TanStack Query 还会额外取消 Promise。
+
+[//]: # 'Example7'
+
+```angular-ts
+@Component({
+ standalone: true,
+ template: `Cancel `,
+})
+export class TodosComponent {
+ query = injectQuery(() => ({
+ queryKey: ['todos'],
+ queryFn: async ({ signal }) => {
+ const resp = await fetch('/todos', { signal })
+ return resp.json()
+ },
+ }))
+
+ queryClient = inject(QueryClient)
+
+ onCancel() {
+ this.queryClient.cancelQueries(['todos'])
+ }
+}
+```
+
+[//]: # 'Example7'
diff --git a/docs/zh-hans/framework/angular/guides/query-functions.md b/docs/zh-hans/framework/angular/guides/query-functions.md
new file mode 100644
index 00000000000..e967bd3e29a
--- /dev/null
+++ b/docs/zh-hans/framework/angular/guides/query-functions.md
@@ -0,0 +1,103 @@
+---
+source-updated-at: '2024-01-26T03:31:25.000Z'
+translation-updated-at: '2025-05-06T04:56:44.357Z'
+id: query-functions
+title: 查询函数
+---
+
+# 查询函数 (Query Functions)
+
+查询函数可以是**任何返回 Promise 的函数**。返回的 Promise 应当**解析数据 (resolve the data)** 或**抛出错误 (throw an error)**。
+
+以下是所有有效的查询函数配置示例:
+
+```ts
+injectQuery(() => ({ queryKey: ['todos'], queryFn: fetchAllTodos }))
+injectQuery(() => ({ queryKey: ['todos', todoId], queryFn: () => fetchTodoById(todoId) })
+injectQuery(() => ({
+ queryKey: ['todos', todoId],
+ queryFn: async () => {
+ const data = await fetchTodoById(todoId)
+ return data
+ },
+}))
+injectQuery(() => ({
+ queryKey: ['todos', todoId],
+ queryFn: ({ queryKey }) => fetchTodoById(queryKey[1]),
+}))
+```
+
+## 错误处理与抛出 (Handling and Throwing Errors)
+
+为了让 TanStack Query 判定查询失败,查询函数**必须抛出错误**或返回一个**被拒绝的 Promise (rejected Promise)**。查询函数中抛出的任何错误都会被持久化到查询的 `error` 状态中。
+
+```ts
+todos = injectQuery(() => ({
+ queryKey: ['todos', todoId()],
+ queryFn: async () => {
+ if (somethingGoesWrong) {
+ throw new Error('Oh no!')
+ }
+ if (somethingElseGoesWrong) {
+ return Promise.reject(new Error('Oh no!'))
+ }
+
+ return data
+ },
+}))
+```
+
+## 与 `fetch` 等默认不抛出错误的客户端一起使用 (Usage with `fetch` and other clients that do not throw by default)
+
+虽然大多数工具如 `axios` 或 `graphql-request` 会自动为失败的 HTTP 调用抛出错误,但像 `fetch` 这样的工具默认不会抛出错误。这种情况下,您需要手动抛出错误。以下是使用流行的 `fetch` API 实现这一点的简单方法:
+
+```ts
+todos = injectQuery(() => ({
+ queryKey: ['todos', todoId()],
+ queryFn: async () => {
+ const response = await fetch('/todos/' + todoId)
+ if (!response.ok) {
+ throw new Error('Network response was not ok')
+ }
+ return response.json()
+ },
+}))
+```
+
+## 查询函数变量 (Query Function Variables)
+
+查询键 (Query keys) 不仅用于唯一标识您要获取的数据,还会作为 QueryFunctionContext 的一部分方便地传递到您的查询函数中。虽然并不总是必要,但这使得在需要时可以提取您的查询函数:
+
+```ts
+result = injectQuery(() => ({
+ queryKey: ['todos', { status: status(), page: page() }],
+ queryFn: fetchTodoList,
+}))
+
+// 在查询函数中访问 key、status 和 page 变量!
+function fetchTodoList({ queryKey }) {
+ const [_key, { status, page }] = queryKey
+ return new Promise()
+}
+```
+
+### 查询函数上下文 (QueryFunctionContext)
+
+`QueryFunctionContext` 是传递给每个查询函数的对象,包含以下属性:
+
+- `queryKey: QueryKey`: [查询键 (Query Keys)](./query-keys.md)
+- `client: QueryClient`: [查询客户端 (QueryClient)](../../../reference/QueryClient.md)
+- `signal?: AbortSignal`
+ - 由 TanStack Query 提供的 [中止信号 (AbortSignal)](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) 实例
+ - 可用于 [查询取消 (Query Cancellation)](./query-cancellation.md)
+- `meta: Record | undefined`
+ - 可选字段,可填充有关查询的附加信息
+
+此外,[无限查询 (Infinite Queries)](./infinite-queries.md) 还会获得以下选项:
+
+- `pageParam: TPageParam`
+ - 用于获取当前页面的页面参数
+- `direction: 'forward' | 'backward'`
+ - **已弃用**
+ - 当前页面获取的方向
+ - 要获取当前页面获取的方向,请从 `getNextPageParam` 和 `getPreviousPageParam` 向 `pageParam` 添加方向参数
diff --git a/docs/zh-hans/framework/angular/guides/query-invalidation.md b/docs/zh-hans/framework/angular/guides/query-invalidation.md
new file mode 100644
index 00000000000..22460a62fb0
--- /dev/null
+++ b/docs/zh-hans/framework/angular/guides/query-invalidation.md
@@ -0,0 +1,118 @@
+---
+source-updated-at: '2024-11-14T21:48:46.000Z'
+translation-updated-at: '2025-05-06T04:53:07.857Z'
+id: query-invalidation
+title: 查询失效
+---
+
+等待查询自动变陈旧(stale)后再重新获取并不总是适用,尤其是当用户操作明确导致某查询数据过期时。为此,`QueryClient` 提供了 `invalidateQueries` 方法,允许您智能地标记查询为陈旧状态,并可能触发重新获取!
+
+```tsx
+// 使缓存中的所有查询失效
+queryClient.invalidateQueries()
+// 使所有以 `todos` 开头的查询键的查询失效
+queryClient.invalidateQueries({ queryKey: ['todos'] })
+```
+
+> 注意:其他使用规范化缓存(normalized caches)的库会尝试通过命令式或模式推断来更新本地查询,而 TanStack Query 提供了工具来避免维护规范化缓存的手动操作,转而采用**定向失效(targeted invalidation)、后台重新获取(background-refetching)以及最终的原子更新(atomic updates)**。
+
+当使用 `invalidateQueries` 使查询失效时,会发生两件事:
+
+- 该查询被标记为陈旧(stale)。此状态会覆盖 `injectQuery` 或相关函数中配置的任何 `staleTime` 值
+- 如果该查询当前正通过 `injectQuery` 或相关函数渲染,还会在后台触发重新获取
+
+## 使用 `invalidateQueries` 进行查询匹配
+
+在使用 `invalidateQueries` 和 `removeQueries` 等支持部分查询匹配的 API 时,您可以通过前缀匹配多个查询,或精确匹配特定查询。关于可用的筛选器类型,请参阅[查询筛选器](./filters.md#query-filters)。
+
+以下示例中,我们使用 `todos` 前缀来使所有查询键以 `todos` 开头的查询失效:
+
+```ts
+import { injectQuery, QueryClient } from '@tanstack/angular-query-experimental'
+
+class QueryInvalidationExample {
+ queryClient = inject(QueryClient)
+
+ invalidateQueries() {
+ this.queryClient.invalidateQueries({ queryKey: ['todos'] })
+ }
+
+ // 以下两个查询都将失效
+ todoListQuery = injectQuery(() => ({
+ queryKey: ['todos'],
+ queryFn: fetchTodoList,
+ }))
+ todoListQuery = injectQuery(() => ({
+ queryKey: ['todos', { page: 1 }],
+ queryFn: fetchTodoList,
+ }))
+}
+```
+
+您还可以通过传递更具体的查询键,使带特定变量的查询失效:
+
+```ts
+queryClient.invalidateQueries({
+ queryKey: ['todos', { type: 'done' }],
+})
+
+// 以下查询将失效
+todoListQuery = injectQuery(() => ({
+ queryKey: ['todos', { type: 'done' }],
+ queryFn: fetchTodoList,
+}))
+
+// 但以下查询不会失效
+todoListQuery = injectQuery(() => ({
+ queryKey: ['todos'],
+ queryFn: fetchTodoList,
+}))
+```
+
+`invalidateQueries` API 非常灵活。如果您**只想**使不包含额外变量或子键的 `todos` 查询失效,可以传递 `exact: true` 选项:
+
+```ts
+queryClient.invalidateQueries({
+ queryKey: ['todos'],
+ exact: true,
+})
+
+// 以下查询将失效
+todoListQuery = injectQuery(() => ({
+ queryKey: ['todos'],
+ queryFn: fetchTodoList,
+}))
+
+// 但以下查询不会失效
+const todoListQuery = injectQuery(() => ({
+ queryKey: ['todos', { type: 'done' }],
+ queryFn: fetchTodoList,
+}))
+```
+
+如果需要**更精细**的控制,可以向 `invalidateQueries` 方法传递一个断言函数。该函数会接收查询缓存中的每个 `Query` 实例,并让您通过返回 `true` 或 `false` 来决定是否使其失效:
+
+```ts
+queryClient.invalidateQueries({
+ predicate: (query) =>
+ query.queryKey[0] === 'todos' && query.queryKey[1]?.version >= 10,
+})
+
+// 以下查询将失效
+todoListQuery = injectQuery(() => ({
+ queryKey: ['todos', { version: 20 }],
+ queryFn: fetchTodoList,
+}))
+
+// 以下查询将失效
+todoListQuery = injectQuery(() => ({
+ queryKey: ['todos', { version: 10 }],
+ queryFn: fetchTodoList,
+}))
+
+// 但以下查询不会失效
+todoListQuery = injectQuery(() => ({
+ queryKey: ['todos', { version: 5 }],
+ queryFn: fetchTodoList,
+}))
+```
diff --git a/docs/zh-hans/framework/angular/guides/query-keys.md b/docs/zh-hans/framework/angular/guides/query-keys.md
new file mode 100644
index 00000000000..c26b1b354b5
--- /dev/null
+++ b/docs/zh-hans/framework/angular/guides/query-keys.md
@@ -0,0 +1,77 @@
+---
+source-updated-at: '2024-01-26T03:31:25.000Z'
+translation-updated-at: '2025-05-06T04:54:01.961Z'
+id: query-keys
+title: 查询键
+---
+
+TanStack Query 的核心是基于查询键 (query keys) 为您管理查询缓存。查询键在顶层必须是一个数组,可以简单到仅包含单个字符串的数组,也可以复杂到包含多个字符串和嵌套对象的数组。只要查询键是可序列化的,并且**能唯一标识查询的数据**,您就可以使用它!
+
+## 简单查询键
+
+最简单的键形式是由常量值组成的数组。这种格式适用于:
+
+- 通用列表/索引资源
+- 非层级化资源
+
+```ts
+// 待办事项列表
+injectQuery(() => ({ queryKey: ['todos'], ... }))
+
+// 其他任意内容!
+injectQuery(() => ({ queryKey: ['something', 'special'], ... }))
+```
+
+## 带变量的数组键
+
+当查询需要更多信息来唯一描述其数据时,您可以使用包含字符串和任意数量可序列化对象的数组。这种形式适用于:
+
+- 层级化或嵌套资源
+ - 通常会传递 ID、索引或其他原始值来唯一标识项
+- 带附加参数的查询
+ - 通常会传递包含附加选项的对象
+
+```ts
+// 单个待办事项
+injectQuery(() => ({queryKey: ['todo', 5], ...}))
+
+// "预览"格式的单个待办事项
+injectQuery(() => ({queryKey: ['todo', 5, {preview: true}], ...}))
+
+// 已完成待办事项列表
+injectQuery(() => ({queryKey: ['todos', {type: 'done'}], ...}))
+```
+
+## 查询键会被确定性哈希!
+
+这意味着无论对象中键的顺序如何,以下所有查询都被视为等同:
+
+```ts
+injectQuery(() => ({ queryKey: ['todos', { status, page }], ... }))
+injectQuery(() => ({ queryKey: ['todos', { page, status }], ...}))
+injectQuery(() => ({ queryKey: ['todos', { page, status, other: undefined }], ... }))
+```
+
+但以下查询键并不等同。数组项的顺序很重要!
+
+```ts
+injectQuery(() => ({ queryKey: ['todos', status, page], ... }))
+injectQuery(() => ({ queryKey: ['todos', page, status], ...}))
+injectQuery(() => ({ queryKey: ['todos', undefined, page, status], ...}))
+```
+
+## 如果查询函数依赖变量,请将其包含在查询键中
+
+由于查询键唯一描述了它们获取的数据,因此应包含查询函数中使用的任何**会变化**的变量。例如:
+
+```ts
+todoId = signal(-1)
+
+injectQuery(() => ({
+ enabled: todoId() > 0,
+ queryKey: ['todos', todoId()],
+ queryFn: () => fetchTodoById(todoId()),
+}))
+```
+
+请注意,查询键充当查询函数的依赖项。将依赖变量添加到查询键可确保查询被独立缓存,并且每当变量变化时,_查询会自动重新获取_(取决于您的 `staleTime` 设置)。更多信息和示例请参阅 [exhaustive-deps](../../../eslint/exhaustive-deps.md) 部分。
diff --git a/docs/zh-hans/framework/angular/guides/query-options.md b/docs/zh-hans/framework/angular/guides/query-options.md
new file mode 100644
index 00000000000..e828e6b2b67
--- /dev/null
+++ b/docs/zh-hans/framework/angular/guides/query-options.md
@@ -0,0 +1,58 @@
+---
+source-updated-at: '2025-02-02T18:26:57.000Z'
+translation-updated-at: '2025-05-06T04:53:28.456Z'
+id: query-options
+title: 查询选项
+---
+
+在多个地方共享 `queryKey` 和 `queryFn` 同时保持它们彼此关联的最佳方式之一是使用 `queryOptions` 辅助函数。在运行时,该辅助函数仅返回传入的内容,但[结合 TypeScript 使用时](../typescript.md#typing-query-options)能提供诸多优势。您可以在一个地方定义查询的所有可能选项,并同时获得类型推断和类型安全。
+
+```ts
+import { queryOptions } from '@tanstack/angular-query-experimental'
+
+@Injectable({
+ providedIn: 'root',
+})
+export class QueriesService {
+ private http = inject(HttpClient)
+
+ post(postId: number) {
+ return queryOptions({
+ queryKey: ['post', postId],
+ queryFn: () => {
+ return lastValueFrom(
+ this.http.get(
+ `https://jsonplaceholder.typicode.com/posts/${postId}`,
+ ),
+ )
+ },
+ })
+ }
+}
+
+// 使用示例:
+
+postId = input.required({
+ transform: numberAttribute,
+})
+queries = inject(QueriesService)
+
+postQuery = injectQuery(() => this.queries.post(this.postId()))
+
+queryClient.prefetchQuery(this.queries.post(23))
+queryClient.setQueryData(this.queries.post(42).queryKey, newPost)
+```
+
+对于无限查询 (Infinite Queries),另有专用的 [`infiniteQueryOptions`](../reference/infiniteQueryOptions.md) 辅助函数可用。
+
+您仍可在组件级别覆盖某些选项。一个非常常见且实用的模式是为每个组件创建 [`select`](./render-optimizations.md#select) 函数:
+
+```ts
+// 类型推断仍然有效,因此 query.data 将是 select 的返回类型而非 queryFn 的返回类型
+queries = inject(QueriesService)
+
+query = injectQuery(() => ({
+ ...groupOptions(1),
+ select: (data) => data.title,
+}))
+```
diff --git a/docs/zh-hans/framework/angular/guides/query-retries.md b/docs/zh-hans/framework/angular/guides/query-retries.md
new file mode 100644
index 00000000000..2c2e742bf38
--- /dev/null
+++ b/docs/zh-hans/framework/angular/guides/query-retries.md
@@ -0,0 +1,65 @@
+---
+source-updated-at: '2024-11-07T15:18:52.000Z'
+translation-updated-at: '2025-05-06T04:56:03.413Z'
+id: query-retries
+title: 查询重试
+---
+
+当 `injectQuery` 查询失败时(查询函数抛出错误),若该查询请求未达到最大连续重试次数(默认为 `3`)或提供了判断是否允许重试的函数,TanStack Query 将自动重试该查询。
+
+您可以在全局级别和单个查询级别配置重试行为:
+
+- 设置 `retry = false` 将禁用重试
+- 设置 `retry = 6` 将在显示函数抛出的最终错误前重试失败请求 6 次
+- 设置 `retry = true` 将无限重试失败请求
+- 设置 `retry = (failureCount, error) => ...` 允许根据失败原因自定义逻辑
+
+```ts
+import { injectQuery } from '@tanstack/angular-query-experimental'
+
+// 使特定查询重试指定次数
+const result = injectQuery(() => ({
+ queryKey: ['todos', 1],
+ queryFn: fetchTodoListPage,
+ retry: 10, // 将在显示错误前重试失败请求 10 次
+}))
+```
+
+> 提示:在最后一次重试尝试前,`error` 属性的内容将作为 `failureReason` 响应属性的一部分存在于 `injectQuery` 中。因此在上例中,前 9 次重试尝试(共 10 次)的任何错误内容都将属于 `failureReason` 属性,若所有重试后错误仍存在,最终它们会在最后一次尝试后成为 `error` 的一部分。
+
+## 重试延迟
+
+默认情况下,TanStack Query 的重试不会在请求失败后立即执行。按照标准做法,每次重试尝试会逐渐增加退避延迟时间。
+
+默认 `retryDelay` 设置为每次尝试翻倍(从 `1000` 毫秒开始),但不超过 30 秒:
+
+```ts
+// 为所有查询配置
+import {
+ QueryCache,
+ QueryClient,
+ QueryClientProvider,
+} from '@tanstack/angular-query-experimental'
+
+const queryClient = new QueryClient({
+ defaultOptions: {
+ queries: {
+ retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 30000),
+ },
+ },
+})
+
+bootstrapApplication(AppComponent, {
+ providers: [provideTanStackQuery(queryClient)],
+})
+```
+
+虽然不推荐,但您显然可以在插件和单个查询选项中覆盖 `retryDelay` 函数/整数值。如果设置为整数而非函数,延迟时间将始终保持不变:
+
+```ts
+const result = injectQuery(() => ({
+ queryKey: ['todos'],
+ queryFn: fetchTodoList,
+ retryDelay: 1000, // 无论重试多少次,始终等待 1000 毫秒后重试
+}))
+```
diff --git a/docs/zh-hans/framework/angular/guides/scroll-restoration.md b/docs/zh-hans/framework/angular/guides/scroll-restoration.md
new file mode 100644
index 00000000000..791f8a2337f
--- /dev/null
+++ b/docs/zh-hans/framework/angular/guides/scroll-restoration.md
@@ -0,0 +1,7 @@
+---
+source-updated-at: '2024-01-26T03:31:25.000Z'
+translation-updated-at: '2025-05-06T04:49:46.983Z'
+id: scroll-restoration
+title: Scroll Restoration
+ref: docs/zh-hans/framework/react/guides/scroll-restoration.md
+---
diff --git a/docs/zh-hans/framework/angular/guides/window-focus-refetching.md b/docs/zh-hans/framework/angular/guides/window-focus-refetching.md
new file mode 100644
index 00000000000..81832485c82
--- /dev/null
+++ b/docs/zh-hans/framework/angular/guides/window-focus-refetching.md
@@ -0,0 +1,42 @@
+---
+source-updated-at: '2025-03-01T21:43:55.000Z'
+translation-updated-at: '2025-05-06T04:49:46.933Z'
+id: window-focus-refetching
+title: Window Focus Refetching
+ref: docs/zh-hans/framework/react/guides/window-focus-refetching.md
+replace:
+ '@tanstack/react-query': '@tanstack/angular-query-experimental'
+---
+
+[//]: # 'Example'
+
+```ts
+export const appConfig: ApplicationConfig = {
+ providers: [
+ provideTanStackQuery(
+ new QueryClient({
+ defaultOptions: {
+ queries: {
+ refetchOnWindowFocus: false, // default: true
+ },
+ },
+ }),
+ ),
+ ],
+}
+```
+
+[//]: # 'Example'
+[//]: # 'Example2'
+
+```ts
+injectQuery(() => ({
+ queryKey: ['todos'],
+ queryFn: fetchTodos,
+ refetchOnWindowFocus: false,
+}))
+```
+
+[//]: # 'Example2'
+[//]: # 'ReactNative'
+[//]: # 'ReactNative'
diff --git a/docs/zh-hans/framework/angular/installation.md b/docs/zh-hans/framework/angular/installation.md
new file mode 100644
index 00000000000..3b8a613c110
--- /dev/null
+++ b/docs/zh-hans/framework/angular/installation.md
@@ -0,0 +1,36 @@
+---
+source-updated-at: '2024-08-19T08:36:40.000Z'
+translation-updated-at: '2025-05-06T04:50:07.866Z'
+id: installation
+title: 安装
+---
+
+> 重要提示:当前该库处于实验阶段。这意味着在次要版本和补丁版本中可能会发生破坏性变更。请谨慎升级。如果您在生产环境中使用此实验阶段的库,请将版本锁定到具体的补丁版本以避免意外的破坏性变更。
+
+### NPM
+
+_Angular Query 兼容 Angular v16 及以上版本_
+
+```bash
+npm i @tanstack/angular-query-experimental
+```
+
+或
+
+```bash
+pnpm add @tanstack/angular-query-experimental
+```
+
+或
+
+```bash
+yarn add @tanstack/angular-query-experimental
+```
+
+或
+
+```bash
+bun add @tanstack/angular-query-experimental
+```
+
+> 想在下载前试用一下?可以尝试 [简单示例](../examples/simple) 或 [基础示例](../examples/basic)!
diff --git a/docs/zh-hans/framework/angular/overview.md b/docs/zh-hans/framework/angular/overview.md
new file mode 100644
index 00000000000..79af75fce07
--- /dev/null
+++ b/docs/zh-hans/framework/angular/overview.md
@@ -0,0 +1,115 @@
+---
+source-updated-at: '2024-11-07T15:18:52.000Z'
+translation-updated-at: '2025-05-06T04:51:31.172Z'
+id: overview
+title: 概述
+---
+
+> 重要提示:该库目前处于实验阶段。这意味着在次要版本和补丁版本中可能会出现破坏性变更。升级时请谨慎操作。如果您在生产环境中使用此实验阶段的库,请将版本锁定到具体的补丁版本以避免意外的破坏性变更。
+
+`@tanstack/angular-query-experimental` 包为通过 Angular 使用 TanStack Query 提供了一流的 API。
+
+## 欢迎反馈!
+
+我们正在努力为 Angular 上的 TanStack Query 提供稳定的 API。如果您有任何反馈意见,请联系我们的 [TanStack Discord](https://tlinz.com/discord) 服务器或在 GitHub 上[参与此讨论](https://github.com/TanStack/query/discussions/6293)。
+
+## 支持的 Angular 版本
+
+TanStack Query 兼容 Angular v16 及以上版本。
+
+TanStack Query(前身为 React Query)常被描述为 Web 应用程序中缺失的数据获取库,但从技术角度而言,它能让 **获取、缓存、同步和更新服务端状态** 在您的 Web 应用中变得轻而易举。
+
+## 动机
+
+大多数核心 Web 框架 **并未** 提供一种全面的数据获取或更新方式。因此,开发者最终要么构建封装了严格数据获取理念的元框架,要么发明自己的数据获取方法。这通常意味着拼凑基于组件的状态和副作用,或者使用更通用的状态管理库来存储和提供整个应用中的异步数据。
+
+虽然大多数传统状态管理库在处理客户端状态时表现优异,但 **在处理异步或服务端状态时并不理想**。这是因为 **服务端状态完全不同**。首先,服务端状态:
+
+- 持久化存储在您可能无法控制或拥有的远程位置
+- 需要异步 API 进行获取和更新
+- 意味着共享所有权,可能被他人更改而您不知情
+- 如果不小心处理,可能在您的应用中变得“过时”
+
+一旦您理解了应用中服务端状态的本质,**更多挑战会随之而来**,例如:
+
+- 缓存...(可能是编程中最难的事情)
+- 将针对相同数据的多个请求去重为单个请求
+- 在后台更新“过时”数据
+- 知道数据何时“过时”
+- 尽可能快地反映数据更新
+- 分页和懒加载数据等性能优化
+- 管理服务端状态的内存和垃圾回收
+- 通过结构共享记忆查询结果
+
+如果这个列表没有让您感到压力,那一定意味着您已经解决了所有服务端状态问题并值得嘉奖。然而,如果您和大多数人一样,可能尚未应对全部或大部分挑战,而我们才刚刚触及表面!
+
+TanStack Query 无疑是管理服务端状态的**最佳**库之一。它**开箱即用、零配置**,并且可以随着应用的增长按需定制。
+
+TanStack Query 让您能够战胜和克服**服务端状态**的棘手挑战,在数据开始控制您之前掌控应用数据。
+
+从技术角度来看,TanStack Query 可能会:
+
+- 帮助您从应用中移除**大量**复杂且难以理解的代码,仅用寥寥几行 TanStack Query 逻辑替代
+- 提高应用的可维护性,轻松构建新功能而无需担心连接新的服务端状态数据源
+- 通过使应用感觉比以往更快、响应更迅速,直接影响最终用户体验
+- 可能帮助您节省带宽并提升内存性能
+
+[//]: # '示例'
+
+## 说够了,直接看代码吧!
+
+在下面的示例中,您可以看到 TanStack Query 最基本和简单的形式,用于获取 TanStack Query GitHub 项目本身的统计信息:
+
+[在 StackBlitz 中打开](https://stackblitz.com/github/TanStack/query/tree/main/examples/angular/simple)
+
+```angular-ts
+import { ChangeDetectionStrategy, Component, inject } from '@angular/core'
+import { HttpClient } from '@angular/common/http'
+import { CommonModule } from '@angular/common'
+import { injectQuery } from '@tanstack/angular-query-experimental'
+import { lastValueFrom } from 'rxjs'
+
+@Component({
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ selector: 'simple-example',
+ standalone: true,
+ template: `
+ @if (query.isPending()) {
+ Loading...
+ }
+ @if (query.error()) {
+ An error has occurred: {{ query.error().message }}
+ }
+ @if (query.data(); as data) {
+ {{ data.name }}
+ {{ data.description }}
+ 👀 {{ data.subscribers_count }}
+ ✨ {{ data.stargazers_count }}
+ 🍴 {{ data.forks_count }}
+ }
+ `
+})
+export class SimpleExampleComponent {
+ http = inject(HttpClient)
+
+ query = injectQuery(() => ({
+ queryKey: ['repoData'],
+ queryFn: () =>
+ lastValueFrom(
+ this.http.get('https://api.github.com/repos/tanstack/query'),
+ ),
+ }))
+}
+
+interface Response {
+ name: string
+ description: string
+ subscribers_count: number
+ stargazers_count: number
+ forks_count: number
+}
+```
+
+## 您说服了我,接下来该怎么做?
+
+- 按照自己的节奏学习 TanStack Query,参考我们详尽的[入门指南](../installation)和[API 参考](../reference/functions/injectquery)
diff --git a/docs/zh-hans/framework/angular/quick-start.md b/docs/zh-hans/framework/angular/quick-start.md
new file mode 100644
index 00000000000..f2b5036d2d2
--- /dev/null
+++ b/docs/zh-hans/framework/angular/quick-start.md
@@ -0,0 +1,120 @@
+---
+source-updated-at: '2024-11-19T18:32:49.000Z'
+translation-updated-at: '2025-05-03T22:08:27.205Z'
+id: quick-start
+title: 快速开始
+---
+
+> 重要提示:当前该库处于实验阶段。这意味着次要版本和补丁版本都可能包含破坏性变更。升级时请谨慎操作。如果在生产环境中使用实验阶段的版本,请锁定到具体的补丁版本以避免意外的破坏性变更。
+
+[//]: # '示例'
+
+如需查看完整功能示例,请参考我们的 [基础 codesandbox 示例](../examples/basic)
+
+### 为应用提供客户端
+
+```ts
+import { provideHttpClient } from '@angular/common/http'
+import {
+ provideTanStackQuery,
+ QueryClient,
+} from '@tanstack/angular-query-experimental'
+
+bootstrapApplication(AppComponent, {
+ providers: [provideHttpClient(), provideTanStackQuery(new QueryClient())],
+})
+```
+
+或在基于 NgModule 的应用中
+
+```ts
+import { provideHttpClient } from '@angular/common/http'
+import {
+ provideTanStackQuery,
+ QueryClient,
+} from '@tanstack/angular-query-experimental'
+
+@NgModule({
+ declarations: [AppComponent],
+ imports: [BrowserModule],
+ providers: [provideTanStackQuery(new QueryClient())],
+ bootstrap: [AppComponent],
+})
+export class AppModule {}
+```
+
+### 包含查询与变更的组件
+
+```angular-ts
+import { Component, Injectable, inject } from '@angular/core'
+import { HttpClient } from '@angular/common/http'
+import { lastValueFrom } from 'rxjs'
+
+import {
+ injectMutation,
+ injectQuery,
+ QueryClient
+} from '@tanstack/angular-query-experimental'
+
+@Component({
+ standalone: true,
+ template: `
+
+
添加待办
+
+
+ @for (todo of query.data(); track todo.title) {
+ {{ todo.title }}
+ }
+
+
+ `,
+})
+export class TodosComponent {
+ todoService = inject(TodoService)
+ queryClient = inject(QueryClient)
+
+ query = injectQuery(() => ({
+ queryKey: ['todos'],
+ queryFn: () => this.todoService.getTodos(),
+ }))
+
+ mutation = injectMutation(() => ({
+ mutationFn: (todo: Todo) => this.todoService.addTodo(todo),
+ onSuccess: () => {
+ this.queryClient.invalidateQueries({ queryKey: ['todos'] })
+ },
+ }))
+
+ onAddTodo() {
+ this.mutation.mutate({
+ id: Date.now().toString(),
+ title: '洗衣服',
+ })
+ }
+}
+
+@Injectable({ providedIn: 'root' })
+export class TodoService {
+ private http = inject(HttpClient)
+
+ getTodos(): Promise {
+ return lastValueFrom(
+ this.http.get('https://jsonplaceholder.typicode.com/todos'),
+ )
+ }
+
+ addTodo(todo: Todo): Promise {
+ return lastValueFrom(
+ this.http.post('https://jsonplaceholder.typicode.com/todos', todo),
+ )
+ }
+}
+
+interface Todo {
+ id: string
+ title: string
+}
+```
+
+[//]: # '示例'
diff --git a/docs/zh-hans/framework/angular/reference/functions/infinitequeryoptions.md b/docs/zh-hans/framework/angular/reference/functions/infinitequeryoptions.md
new file mode 100644
index 00000000000..405c454fbcd
--- /dev/null
+++ b/docs/zh-hans/framework/angular/reference/functions/infinitequeryoptions.md
@@ -0,0 +1,134 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:03:17.816Z'
+id: infiniteQueryOptions
+title: infiniteQueryOptions
+---
+
+# Function: infiniteQueryOptions()
+
+Allows to share and re-use infinite query options in a type-safe way.
+
+The `queryKey` will be tagged with the type from `queryFn`.
+
+## Param
+
+The infinite query options to tag with the type from `queryFn`.
+
+## infiniteQueryOptions(options)
+
+```ts
+function infiniteQueryOptions<
+ TQueryFnData,
+ TError,
+ TData,
+ TQueryKey,
+ TPageParam,
+>(
+ options,
+): UndefinedInitialDataInfiniteOptions<
+ TQueryFnData,
+ TError,
+ TData,
+ TQueryKey,
+ TPageParam
+> &
+ object
+```
+
+Allows to share and re-use infinite query options in a type-safe way.
+
+The `queryKey` will be tagged with the type from `queryFn`.
+
+### Type Parameters
+
+• **TQueryFnData**
+
+• **TError** = `Error`
+
+• **TData** = `InfiniteData`\<`TQueryFnData`, `unknown`\>
+
+• **TQueryKey** _extends_ `QueryKey` = `QueryKey`
+
+• **TPageParam** = `unknown`
+
+### Parameters
+
+• **options**: [`UndefinedInitialDataInfiniteOptions`](../type-aliases/undefinedinitialdatainfiniteoptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`, `TPageParam`\>
+
+The infinite query options to tag with the type from `queryFn`.
+
+### Returns
+
+[`UndefinedInitialDataInfiniteOptions`](../type-aliases/undefinedinitialdatainfiniteoptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`, `TPageParam`\> & `object`
+
+The tagged infinite query options.
+
+The tagged infinite query options.
+
+### Param
+
+The infinite query options to tag with the type from `queryFn`.
+
+### Defined in
+
+[infinite-query-options.ts:59](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/infinite-query-options.ts#L59)
+
+## infiniteQueryOptions(options)
+
+```ts
+function infiniteQueryOptions<
+ TQueryFnData,
+ TError,
+ TData,
+ TQueryKey,
+ TPageParam,
+>(
+ options,
+): DefinedInitialDataInfiniteOptions<
+ TQueryFnData,
+ TError,
+ TData,
+ TQueryKey,
+ TPageParam
+> &
+ object
+```
+
+Allows to share and re-use infinite query options in a type-safe way.
+
+The `queryKey` will be tagged with the type from `queryFn`.
+
+### Type Parameters
+
+• **TQueryFnData**
+
+• **TError** = `Error`
+
+• **TData** = `InfiniteData`\<`TQueryFnData`, `unknown`\>
+
+• **TQueryKey** _extends_ `QueryKey` = `QueryKey`
+
+• **TPageParam** = `unknown`
+
+### Parameters
+
+• **options**: [`DefinedInitialDataInfiniteOptions`](../type-aliases/definedinitialdatainfiniteoptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`, `TPageParam`\>
+
+The infinite query options to tag with the type from `queryFn`.
+
+### Returns
+
+[`DefinedInitialDataInfiniteOptions`](../type-aliases/definedinitialdatainfiniteoptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`, `TPageParam`\> & `object`
+
+The tagged infinite query options.
+
+The tagged infinite query options.
+
+### Param
+
+The infinite query options to tag with the type from `queryFn`.
+
+### Defined in
+
+[infinite-query-options.ts:91](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/infinite-query-options.ts#L91)
diff --git a/docs/zh-hans/framework/angular/reference/functions/injectinfinitequery.md b/docs/zh-hans/framework/angular/reference/functions/injectinfinitequery.md
new file mode 100644
index 00000000000..7cee4c63ee0
--- /dev/null
+++ b/docs/zh-hans/framework/angular/reference/functions/injectinfinitequery.md
@@ -0,0 +1,190 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:03:17.757Z'
+id: injectInfiniteQuery
+title: injectInfiniteQuery
+---
+
+# Function: injectInfiniteQuery()
+
+Injects an infinite query: a declarative dependency on an asynchronous source of data that is tied to a unique key.
+Infinite queries can additively "load more" data onto an existing set of data or "infinite scroll"
+
+## Param
+
+A function that returns infinite query options.
+
+## Param
+
+The Angular injector to use.
+
+## injectInfiniteQuery(optionsFn, injector)
+
+```ts
+function injectInfiniteQuery<
+ TQueryFnData,
+ TError,
+ TData,
+ TQueryKey,
+ TPageParam,
+>(optionsFn, injector?): CreateInfiniteQueryResult
+```
+
+Injects an infinite query: a declarative dependency on an asynchronous source of data that is tied to a unique key.
+Infinite queries can additively "load more" data onto an existing set of data or "infinite scroll"
+
+### Type Parameters
+
+• **TQueryFnData**
+
+• **TError** = `Error`
+
+• **TData** = `InfiniteData`\<`TQueryFnData`, `unknown`\>
+
+• **TQueryKey** _extends_ `QueryKey` = `QueryKey`
+
+• **TPageParam** = `unknown`
+
+### Parameters
+
+• **optionsFn**
+
+A function that returns infinite query options.
+
+• **injector?**: `Injector`
+
+The Angular injector to use.
+
+### Returns
+
+[`CreateInfiniteQueryResult`](../type-aliases/createinfinitequeryresult.md)\<`TData`, `TError`\>
+
+The infinite query result.
+
+The infinite query result.
+
+### Param
+
+A function that returns infinite query options.
+
+### Param
+
+The Angular injector to use.
+
+### Defined in
+
+[inject-infinite-query.ts:30](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/inject-infinite-query.ts#L30)
+
+## injectInfiniteQuery(optionsFn, injector)
+
+```ts
+function injectInfiniteQuery<
+ TQueryFnData,
+ TError,
+ TData,
+ TQueryKey,
+ TPageParam,
+>(optionsFn, injector?): DefinedCreateInfiniteQueryResult
+```
+
+Injects an infinite query: a declarative dependency on an asynchronous source of data that is tied to a unique key.
+Infinite queries can additively "load more" data onto an existing set of data or "infinite scroll"
+
+### Type Parameters
+
+• **TQueryFnData**
+
+• **TError** = `Error`
+
+• **TData** = `InfiniteData`\<`TQueryFnData`, `unknown`\>
+
+• **TQueryKey** _extends_ `QueryKey` = `QueryKey`
+
+• **TPageParam** = `unknown`
+
+### Parameters
+
+• **optionsFn**
+
+A function that returns infinite query options.
+
+• **injector?**: `Injector`
+
+The Angular injector to use.
+
+### Returns
+
+[`DefinedCreateInfiniteQueryResult`](../type-aliases/definedcreateinfinitequeryresult.md)\<`TData`, `TError`\>
+
+The infinite query result.
+
+The infinite query result.
+
+### Param
+
+A function that returns infinite query options.
+
+### Param
+
+The Angular injector to use.
+
+### Defined in
+
+[inject-infinite-query.ts:57](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/inject-infinite-query.ts#L57)
+
+## injectInfiniteQuery(optionsFn, injector)
+
+```ts
+function injectInfiniteQuery<
+ TQueryFnData,
+ TError,
+ TData,
+ TQueryKey,
+ TPageParam,
+>(optionsFn, injector?): CreateInfiniteQueryResult
+```
+
+Injects an infinite query: a declarative dependency on an asynchronous source of data that is tied to a unique key.
+Infinite queries can additively "load more" data onto an existing set of data or "infinite scroll"
+
+### Type Parameters
+
+• **TQueryFnData**
+
+• **TError** = `Error`
+
+• **TData** = `InfiniteData`\<`TQueryFnData`, `unknown`\>
+
+• **TQueryKey** _extends_ `QueryKey` = `QueryKey`
+
+• **TPageParam** = `unknown`
+
+### Parameters
+
+• **optionsFn**
+
+A function that returns infinite query options.
+
+• **injector?**: `Injector`
+
+The Angular injector to use.
+
+### Returns
+
+[`CreateInfiniteQueryResult`](../type-aliases/createinfinitequeryresult.md)\<`TData`, `TError`\>
+
+The infinite query result.
+
+The infinite query result.
+
+### Param
+
+A function that returns infinite query options.
+
+### Param
+
+The Angular injector to use.
+
+### Defined in
+
+[inject-infinite-query.ts:84](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/inject-infinite-query.ts#L84)
diff --git a/docs/zh-hans/framework/angular/reference/functions/injectisfetching.md b/docs/zh-hans/framework/angular/reference/functions/injectisfetching.md
new file mode 100644
index 00000000000..95733f29320
--- /dev/null
+++ b/docs/zh-hans/framework/angular/reference/functions/injectisfetching.md
@@ -0,0 +1,37 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:03:17.704Z'
+id: injectIsFetching
+title: injectIsFetching
+---
+
+# Function: injectIsFetching()
+
+```ts
+function injectIsFetching(filters?, injector?): Signal
+```
+
+Injects a signal that tracks the number of queries that your application is loading or
+fetching in the background.
+
+Can be used for app-wide loading indicators
+
+## Parameters
+
+• **filters?**: `QueryFilters`
+
+The filters to apply to the query.
+
+• **injector?**: `Injector`
+
+The Angular injector to use.
+
+## Returns
+
+`Signal`\<`number`\>
+
+signal with number of loading or fetching queries.
+
+## Defined in
+
+[inject-is-fetching.ts:17](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/inject-is-fetching.ts#L17)
diff --git a/docs/zh-hans/framework/angular/reference/functions/injectismutating.md b/docs/zh-hans/framework/angular/reference/functions/injectismutating.md
new file mode 100644
index 00000000000..cb224beb0ff
--- /dev/null
+++ b/docs/zh-hans/framework/angular/reference/functions/injectismutating.md
@@ -0,0 +1,36 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:03:17.631Z'
+id: injectIsMutating
+title: injectIsMutating
+---
+
+# Function: injectIsMutating()
+
+```ts
+function injectIsMutating(filters?, injector?): Signal
+```
+
+Injects a signal that tracks the number of mutations that your application is fetching.
+
+Can be used for app-wide loading indicators
+
+## Parameters
+
+• **filters?**: `MutationFilters`
+
+The filters to apply to the query.
+
+• **injector?**: `Injector`
+
+The Angular injector to use.
+
+## Returns
+
+`Signal`\<`number`\>
+
+signal with number of fetching mutations.
+
+## Defined in
+
+[inject-is-mutating.ts:16](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/inject-is-mutating.ts#L16)
diff --git a/docs/zh-hans/framework/angular/reference/functions/injectmutation.md b/docs/zh-hans/framework/angular/reference/functions/injectmutation.md
new file mode 100644
index 00000000000..5639769da43
--- /dev/null
+++ b/docs/zh-hans/framework/angular/reference/functions/injectmutation.md
@@ -0,0 +1,49 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:09:50.452Z'
+id: injectMutation
+title: 函数 / injectMutation
+---
+
+# 函数: injectMutation()
+
+```ts
+function injectMutation(
+ optionsFn,
+ injector?,
+): CreateMutationResult
+```
+
+注入一个变更操作 (mutation):这是一个可被调用的命令式函数,通常用于执行服务端副作用。
+
+与查询 (queries) 不同,变更操作不会自动执行。
+
+## 类型参数
+
+• **TData** = `unknown`
+
+• **TError** = `Error`
+
+• **TVariables** = `void`
+
+• **TContext** = `unknown`
+
+## 参数
+
+• **optionsFn**
+
+返回变更操作选项的函数。
+
+• **injector?**: `Injector`
+
+要使用的 Angular 注入器 (injector)。
+
+## 返回值
+
+[`CreateMutationResult`](../type-aliases/createmutationresult.md)\<`TData`, `TError`, `TVariables`, `TContext`\>
+
+变更操作实例。
+
+## 定义位置
+
+[inject-mutation.ts:38](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/inject-mutation.ts#L38)
diff --git a/docs/zh-hans/framework/angular/reference/functions/injectmutationstate.md b/docs/zh-hans/framework/angular/reference/functions/injectmutationstate.md
new file mode 100644
index 00000000000..404edab4bbe
--- /dev/null
+++ b/docs/zh-hans/framework/angular/reference/functions/injectmutationstate.md
@@ -0,0 +1,41 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:03:00.306Z'
+id: injectMutationState
+title: injectMutationState
+---
+
+# Function: injectMutationState()
+
+```ts
+function injectMutationState(
+ mutationStateOptionsFn,
+ options?,
+): Signal
+```
+
+Injects a signal that tracks the state of all mutations.
+
+## Type Parameters
+
+• **TResult** = `MutationState`\<`unknown`, `Error`, `unknown`, `unknown`\>
+
+## Parameters
+
+• **mutationStateOptionsFn** = `...`
+
+A function that returns mutation state options.
+
+• **options?**: [`InjectMutationStateOptions`](../interfaces/injectmutationstateoptions.md)
+
+The Angular injector to use.
+
+## Returns
+
+`Signal`\<`TResult`[]\>
+
+The signal that tracks the state of all mutations.
+
+## Defined in
+
+[inject-mutation-state.ts:53](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/inject-mutation-state.ts#L53)
diff --git a/docs/zh-hans/framework/angular/reference/functions/injectqueries.md b/docs/zh-hans/framework/angular/reference/functions/injectqueries.md
new file mode 100644
index 00000000000..27c9e9abe8d
--- /dev/null
+++ b/docs/zh-hans/framework/angular/reference/functions/injectqueries.md
@@ -0,0 +1,39 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:03:00.233Z'
+id: injectQueries
+title: injectQueries
+---
+
+# Function: injectQueries()
+
+```ts
+function injectQueries(
+ __namedParameters,
+ injector?,
+): Signal
+```
+
+## Type Parameters
+
+• **T** _extends_ `any`[]
+
+• **TCombinedResult** = `T` _extends_ [] ? [] : `T` _extends_ [`Head`] ? [`GetResults`\<`Head`\>] : `T` _extends_ [`Head`, `...Tail[]`] ? [`...Tail[]`] _extends_ [] ? [] : [`...Tail[]`] _extends_ [`Head`] ? [`GetResults`\<`Head`\>, `GetResults`\<`Head`\>] : [`...Tail[]`] _extends_ [`Head`, `...Tail[]`] ? [`...Tail[]`] _extends_ [] ? [] : [`...Tail[]`] _extends_ [`Head`] ? [`GetResults`\<`Head`\>, `GetResults`\<`Head`\>, `GetResults`\<`Head`\>] : [`...Tail[]`] _extends_ [`Head`, `...Tail[]`] ? [`...(...)[]`] _extends_ [] ? [] : ... _extends_ ... ? ... : ... : [`...(...)[]`] _extends_ ...[] ? ...[] : ...[] : [`...Tail[]`] _extends_ `QueryObserverOptionsForCreateQueries`\<`TQueryFnData`, `TError`, `TData`, `any`\>[] ? `QueryObserverResult`\<`unknown` _extends_ `TData` ? `TQueryFnData` : `TData`, `unknown` _extends_ `TError` ? `Error` : `TError`\>[] : `QueryObserverResult`[] : `T` _extends_ `QueryObserverOptionsForCreateQueries`\<`TQueryFnData`, `TError`, `TData`, `any`\>[] ? `QueryObserverResult`\<`unknown` _extends_ `TData` ? `TQueryFnData` : `TData`, `unknown` _extends_ `TError` ? `Error` : `TError`\>[] : `QueryObserverResult`[]
+
+## Parameters
+
+• **\_\_namedParameters**
+
+• **\_\_namedParameters.combine?**
+
+• **\_\_namedParameters.queries?**: `Signal`\<[`...(T extends [] ? [] : T extends [Head] ? [GetOptions] : T extends [Head, ...Tail[]] ? [...Tail[]] extends [] ? [] : [...Tail[]] extends [Head] ? [GetOptions, GetOptions] : [...Tail[]] extends [Head, ...Tail[]] ? [...(...)[]] extends [] ? [] : (...) extends (...) ? (...) : (...) : readonly (...)[] extends [...(...)[]] ? [...(...)[]] : (...) extends (...) ? (...) : (...) : readonly unknown[] extends T ? T : T extends QueryObserverOptionsForCreateQueries[] ? QueryObserverOptionsForCreateQueries[] : QueryObserverOptionsForCreateQueries[])[]`]\>
+
+• **injector?**: `Injector`
+
+## Returns
+
+`Signal`\<`TCombinedResult`\>
+
+## Defined in
+
+[inject-queries.ts:188](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/inject-queries.ts#L188)
diff --git a/docs/zh-hans/framework/angular/reference/functions/injectquery.md b/docs/zh-hans/framework/angular/reference/functions/injectquery.md
new file mode 100644
index 00000000000..03429a6ca1d
--- /dev/null
+++ b/docs/zh-hans/framework/angular/reference/functions/injectquery.md
@@ -0,0 +1,319 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:09:34.795Z'
+id: injectQuery
+title: 函数 / injectQuery
+---
+
+# 函数: injectQuery()
+
+注入一个查询:声明式依赖与异步数据源的绑定关系,该数据源与唯一键相关联。
+
+**基础示例**
+
+```ts
+class ServiceOrComponent {
+ query = injectQuery(() => ({
+ queryKey: ['repoData'],
+ queryFn: () =>
+ this.#http.get('https://api.github.com/repos/tanstack/query'),
+ }))
+}
+```
+
+类似于 Angular 中的 `computed`,传递给 `injectQuery` 的函数将在响应式上下文中运行。
+在下面的示例中,当 filter 信号变为真值时,查询会自动启用并执行。当 filter 信号变回假值时,查询将被禁用。
+
+**响应式示例**
+
+```ts
+class ServiceOrComponent {
+ filter = signal('')
+
+ todosQuery = injectQuery(() => ({
+ queryKey: ['todos', this.filter()],
+ queryFn: () => fetchTodos(this.filter()),
+ // 信号可以与表达式结合使用
+ enabled: !!this.filter(),
+ }))
+}
+```
+
+## 参数
+
+返回查询选项的函数。
+
+## 参数
+
+要使用的 Angular 注入器。
+
+## 参见
+
+https://tanstack.com/query/latest/docs/framework/angular/guides/queries
+
+## injectQuery(optionsFn, injector)
+
+```ts
+function injectQuery(
+ optionsFn,
+ injector?,
+): DefinedCreateQueryResult
+```
+
+注入一个查询:声明式依赖与异步数据源的绑定关系,该数据源与唯一键相关联。
+
+**基础示例**
+
+```ts
+class ServiceOrComponent {
+ query = injectQuery(() => ({
+ queryKey: ['repoData'],
+ queryFn: () =>
+ this.#http.get('https://api.github.com/repos/tanstack/query'),
+ }))
+}
+```
+
+类似于 Angular 中的 `computed`,传递给 `injectQuery` 的函数将在响应式上下文中运行。
+在下面的示例中,当 filter 信号变为真值时,查询会自动启用并执行。当 filter 信号变回假值时,查询将被禁用。
+
+**响应式示例**
+
+```ts
+class ServiceOrComponent {
+ filter = signal('')
+
+ todosQuery = injectQuery(() => ({
+ queryKey: ['todos', this.filter()],
+ queryFn: () => fetchTodos(this.filter()),
+ // 信号可以与表达式结合使用
+ enabled: !!this.filter(),
+ }))
+}
+```
+
+### 类型参数
+
+• **TQueryFnData** = `unknown`
+
+• **TError** = `Error`
+
+• **TData** = `TQueryFnData`
+
+• **TQueryKey** _继承_ `QueryKey` = `QueryKey`
+
+### 参数
+
+• **optionsFn**
+
+返回查询选项的函数。
+
+• **injector?**: `Injector`
+
+要使用的 Angular 注入器。
+
+### 返回值
+
+[`DefinedCreateQueryResult`](../type-aliases/definedcreatequeryresult.md)\<`TData`, `TError`\>
+
+查询结果。
+
+查询结果。
+
+### 参数
+
+返回查询选项的函数。
+
+### 参数
+
+要使用的 Angular 注入器。
+
+### 参见
+
+https://tanstack.com/query/latest/docs/framework/angular/guides/queries
+
+### 参见
+
+https://tanstack.com/query/latest/docs/framework/angular/guides/queries
+
+### 定义于
+
+[inject-query.ts:53](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/inject-query.ts#L53)
+
+## injectQuery(optionsFn, injector)
+
+```ts
+function injectQuery(
+ optionsFn,
+ injector?,
+): CreateQueryResult
+```
+
+注入一个查询:声明式依赖与异步数据源的绑定关系,该数据源与唯一键相关联。
+
+**基础示例**
+
+```ts
+class ServiceOrComponent {
+ query = injectQuery(() => ({
+ queryKey: ['repoData'],
+ queryFn: () =>
+ this.#http.get('https://api.github.com/repos/tanstack/query'),
+ }))
+}
+```
+
+类似于 Angular 中的 `computed`,传递给 `injectQuery` 的函数将在响应式上下文中运行。
+在下面的示例中,当 filter 信号变为真值时,查询会自动启用并执行。当 filter 信号变回假值时,查询将被禁用。
+
+**响应式示例**
+
+```ts
+class ServiceOrComponent {
+ filter = signal('')
+
+ todosQuery = injectQuery(() => ({
+ queryKey: ['todos', this.filter()],
+ queryFn: () => fetchTodos(this.filter()),
+ // 信号可以与表达式结合使用
+ enabled: !!this.filter(),
+ }))
+}
+```
+
+### 类型参数
+
+• **TQueryFnData** = `unknown`
+
+• **TError** = `Error`
+
+• **TData** = `TQueryFnData`
+
+• **TQueryKey** _继承_ `QueryKey` = `QueryKey`
+
+### 参数
+
+• **optionsFn**
+
+返回查询选项的函数。
+
+• **injector?**: `Injector`
+
+要使用的 Angular 注入器。
+
+### 返回值
+
+[`CreateQueryResult`](../type-aliases/createqueryresult.md)\<`TData`, `TError`\>
+
+查询结果。
+
+查询结果。
+
+### 参数
+
+返回查询选项的函数。
+
+### 参数
+
+要使用的 Angular 注入器。
+
+### 参见
+
+https://tanstack.com/query/latest/docs/framework/angular/guides/queries
+
+### 参见
+
+https://tanstack.com/query/latest/docs/framework/angular/guides/queries
+
+### 定义于
+
+[inject-query.ts:102](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/inject-query.ts#L102)
+
+## injectQuery(optionsFn, injector)
+
+```ts
+function injectQuery(
+ optionsFn,
+ injector?,
+): CreateQueryResult
+```
+
+注入一个查询:声明式依赖与异步数据源的绑定关系,该数据源与唯一键相关联。
+
+**基础示例**
+
+```ts
+class ServiceOrComponent {
+ query = injectQuery(() => ({
+ queryKey: ['repoData'],
+ queryFn: () =>
+ this.#http.get('https://api.github.com/repos/tanstack/query'),
+ }))
+}
+```
+
+类似于 Angular 中的 `computed`,传递给 `injectQuery` 的函数将在响应式上下文中运行。
+在下面的示例中,当 filter 信号变为真值时,查询会自动启用并执行。当 filter 信号变回假值时,查询将被禁用。
+
+**响应式示例**
+
+```ts
+class ServiceOrComponent {
+ filter = signal('')
+
+ todosQuery = injectQuery(() => ({
+ queryKey: ['todos', this.filter()],
+ queryFn: () => fetchTodos(this.filter()),
+ // 信号可以与表达式结合使用
+ enabled: !!this.filter(),
+ }))
+}
+```
+
+### 类型参数
+
+• **TQueryFnData** = `unknown`
+
+• **TError** = `Error`
+
+• **TData** = `TQueryFnData`
+
+• **TQueryKey** _继承_ `QueryKey` = `QueryKey`
+
+### 参数
+
+• **optionsFn**
+
+返回查询选项的函数。
+
+• **injector?**: `Injector`
+
+要使用的 Angular 注入器。
+
+### 返回值
+
+[`CreateQueryResult`](../type-aliases/createqueryresult.md)\<`TData`, `TError`\>
+
+查询结果。
+
+查询结果。
+
+### 参数
+
+返回查询选项的函数。
+
+### 参数
+
+要使用的 Angular 注入器。
+
+### 参见
+
+https://tanstack.com/query/latest/docs/framework/angular/guides/queries
+
+### 参见
+
+https://tanstack.com/query/latest/docs/framework/angular/guides/queries
+
+### 定义于
+
+[inject-query.ts:151](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/inject-query.ts#L151)
diff --git a/docs/zh-hans/framework/angular/reference/functions/injectqueryclient.md b/docs/zh-hans/framework/angular/reference/functions/injectqueryclient.md
new file mode 100644
index 00000000000..1ff9b435ff4
--- /dev/null
+++ b/docs/zh-hans/framework/angular/reference/functions/injectqueryclient.md
@@ -0,0 +1,90 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:02:49.756Z'
+id: injectQueryClient
+title: injectQueryClient
+---
+
+# Function: injectQueryClient()
+
+Injects the `QueryClient` instance into the component or service.
+
+**Example**
+
+```ts
+const queryClient = injectQueryClient()
+```
+
+## injectQueryClient()
+
+```ts
+function injectQueryClient(): QueryClient
+```
+
+Injects the `QueryClient` instance into the component or service.
+
+**Example**
+
+```ts
+const queryClient = injectQueryClient()
+```
+
+### Returns
+
+`QueryClient`
+
+### Defined in
+
+[inject-query-client.ts:16](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/inject-query-client.ts#L16)
+
+## injectQueryClient(injectOptions)
+
+```ts
+function injectQueryClient(injectOptions): QueryClient
+```
+
+Injects the `QueryClient` instance into the component or service.
+
+**Example**
+
+```ts
+const queryClient = injectQueryClient()
+```
+
+### Parameters
+
+• **injectOptions**: `InjectOptions` & `object` & `object`
+
+### Returns
+
+`QueryClient`
+
+### Defined in
+
+[inject-query-client.ts:16](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/inject-query-client.ts#L16)
+
+## injectQueryClient(injectOptions)
+
+```ts
+function injectQueryClient(injectOptions): null | QueryClient
+```
+
+Injects the `QueryClient` instance into the component or service.
+
+**Example**
+
+```ts
+const queryClient = injectQueryClient()
+```
+
+### Parameters
+
+• **injectOptions**: `InjectOptions` & `object`
+
+### Returns
+
+`null` \| `QueryClient`
+
+### Defined in
+
+[inject-query-client.ts:16](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/inject-query-client.ts#L16)
diff --git a/docs/zh-hans/framework/angular/reference/functions/provideangularquery.md b/docs/zh-hans/framework/angular/reference/functions/provideangularquery.md
new file mode 100644
index 00000000000..a2b15403ab5
--- /dev/null
+++ b/docs/zh-hans/framework/angular/reference/functions/provideangularquery.md
@@ -0,0 +1,66 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:02:49.704Z'
+id: provideAngularQuery
+title: provideAngularQuery
+---
+
+# Function: provideAngularQuery()
+
+```ts
+function provideAngularQuery(queryClient): EnvironmentProviders
+```
+
+Sets up providers necessary to enable TanStack Query functionality for Angular applications.
+
+Allows to configure a `QueryClient`.
+
+**Example - standalone**
+
+```ts
+import {
+ provideAngularQuery,
+ QueryClient,
+} from '@tanstack/angular-query-experimental'
+
+bootstrapApplication(AppComponent, {
+ providers: [provideAngularQuery(new QueryClient())],
+})
+```
+
+**Example - NgModule-based**
+
+```ts
+import {
+ provideAngularQuery,
+ QueryClient,
+} from '@tanstack/angular-query-experimental'
+
+@NgModule({
+ declarations: [AppComponent],
+ imports: [BrowserModule],
+ providers: [provideAngularQuery(new QueryClient())],
+ bootstrap: [AppComponent],
+})
+export class AppModule {}
+```
+
+## Parameters
+
+• **queryClient**: `QueryClient`
+
+A `QueryClient` instance.
+
+## Returns
+
+`EnvironmentProviders`
+
+A set of providers to set up TanStack Query.
+
+## See
+
+https://tanstack.com/query/v5/docs/framework/angular/quick-start
+
+## Defined in
+
+[providers.ts:50](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/providers.ts#L50)
diff --git a/docs/zh-hans/framework/angular/reference/functions/providequeryclient.md b/docs/zh-hans/framework/angular/reference/functions/providequeryclient.md
new file mode 100644
index 00000000000..43d229204e1
--- /dev/null
+++ b/docs/zh-hans/framework/angular/reference/functions/providequeryclient.md
@@ -0,0 +1,29 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:02:49.668Z'
+id: provideQueryClient
+title: provideQueryClient
+---
+
+# Function: provideQueryClient()
+
+```ts
+function provideQueryClient(value): Provider
+```
+
+Usually [provideAngularQuery](provideangularquery.md) is used once to set up TanStack Query and the
+[https://tanstack.com/query/latest/docs/reference/QueryClient|QueryClient](https://tanstack.com/query/latest/docs/reference/QueryClient|QueryClient)
+for the entire application. You can use `provideQueryClient` to provide a
+different `QueryClient` instance for a part of the application.
+
+## Parameters
+
+• **value**: `QueryClient` \| () => `QueryClient`
+
+## Returns
+
+`Provider`
+
+## Defined in
+
+[inject-query-client.ts:25](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/inject-query-client.ts#L25)
diff --git a/docs/zh-hans/framework/angular/reference/functions/queryoptions.md b/docs/zh-hans/framework/angular/reference/functions/queryoptions.md
new file mode 100644
index 00000000000..7cbd9551e26
--- /dev/null
+++ b/docs/zh-hans/framework/angular/reference/functions/queryoptions.md
@@ -0,0 +1,146 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:02:49.626Z'
+id: queryOptions
+title: queryOptions
+---
+
+# Function: queryOptions()
+
+Allows to share and re-use query options in a type-safe way.
+
+The `queryKey` will be tagged with the type from `queryFn`.
+
+**Example**
+
+```ts
+const { queryKey } = queryOptions({
+ queryKey: ['key'],
+ queryFn: () => Promise.resolve(5),
+ // ^? Promise
+})
+
+const queryClient = new QueryClient()
+const data = queryClient.getQueryData(queryKey)
+// ^? number | undefined
+```
+
+## Param
+
+The query options to tag with the type from `queryFn`.
+
+## queryOptions(options)
+
+```ts
+function queryOptions(
+ options,
+): UndefinedInitialDataOptions & object
+```
+
+Allows to share and re-use query options in a type-safe way.
+
+The `queryKey` will be tagged with the type from `queryFn`.
+
+**Example**
+
+```ts
+const { queryKey } = queryOptions({
+ queryKey: ['key'],
+ queryFn: () => Promise.resolve(5),
+ // ^? Promise
+})
+
+const queryClient = new QueryClient()
+const data = queryClient.getQueryData(queryKey)
+// ^? number | undefined
+```
+
+### Type Parameters
+
+• **TQueryFnData** = `unknown`
+
+• **TError** = `Error`
+
+• **TData** = `TQueryFnData`
+
+• **TQueryKey** _extends_ `QueryKey` = `QueryKey`
+
+### Parameters
+
+• **options**: [`UndefinedInitialDataOptions`](../type-aliases/undefinedinitialdataoptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`\>
+
+The query options to tag with the type from `queryFn`.
+
+### Returns
+
+[`UndefinedInitialDataOptions`](../type-aliases/undefinedinitialdataoptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`\> & `object`
+
+The tagged query options.
+
+The tagged query options.
+
+### Param
+
+The query options to tag with the type from `queryFn`.
+
+### Defined in
+
+[query-options.ts:52](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/query-options.ts#L52)
+
+## queryOptions(options)
+
+```ts
+function queryOptions(
+ options,
+): DefinedInitialDataOptions & object
+```
+
+Allows to share and re-use query options in a type-safe way.
+
+The `queryKey` will be tagged with the type from `queryFn`.
+
+**Example**
+
+```ts
+const { queryKey } = queryOptions({
+ queryKey: ['key'],
+ queryFn: () => Promise.resolve(5),
+ // ^? Promise
+})
+
+const queryClient = new QueryClient()
+const data = queryClient.getQueryData(queryKey)
+// ^? number | undefined
+```
+
+### Type Parameters
+
+• **TQueryFnData** = `unknown`
+
+• **TError** = `Error`
+
+• **TData** = `TQueryFnData`
+
+• **TQueryKey** _extends_ `QueryKey` = `QueryKey`
+
+### Parameters
+
+• **options**: [`DefinedInitialDataOptions`](../type-aliases/definedinitialdataoptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`\>
+
+The query options to tag with the type from `queryFn`.
+
+### Returns
+
+[`DefinedInitialDataOptions`](../type-aliases/definedinitialdataoptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`\> & `object`
+
+The tagged query options.
+
+The tagged query options.
+
+### Param
+
+The query options to tag with the type from `queryFn`.
+
+### Defined in
+
+[query-options.ts:85](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/query-options.ts#L85)
diff --git a/docs/zh-hans/framework/angular/reference/index.md b/docs/zh-hans/framework/angular/reference/index.md
new file mode 100644
index 00000000000..e6ff8f4cc06
--- /dev/null
+++ b/docs/zh-hans/framework/angular/reference/index.md
@@ -0,0 +1,52 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T04:49:47.023Z'
+id: '@tanstack/angular-query-experimental'
+title: '@tanstack/angular-query-experimental'
+---
+
+# @tanstack/angular-query-experimental
+
+## Interfaces
+
+- [BaseMutationNarrowing](interfaces/basemutationnarrowing.md)
+- [BaseQueryNarrowing](interfaces/basequerynarrowing.md)
+- [CreateBaseQueryOptions](interfaces/createbasequeryoptions.md)
+- [CreateInfiniteQueryOptions](interfaces/createinfinitequeryoptions.md)
+- [CreateMutationOptions](interfaces/createmutationoptions.md)
+- [CreateQueryOptions](interfaces/createqueryoptions.md)
+- [InjectMutationStateOptions](interfaces/injectmutationstateoptions.md)
+
+## Type Aliases
+
+- [CreateBaseMutationResult](type-aliases/createbasemutationresult.md)
+- [CreateBaseQueryResult](type-aliases/createbasequeryresult.md)
+- [CreateInfiniteQueryResult](type-aliases/createinfinitequeryresult.md)
+- [CreateMutateAsyncFunction](type-aliases/createmutateasyncfunction.md)
+- [CreateMutateFunction](type-aliases/createmutatefunction.md)
+- [CreateMutationResult](type-aliases/createmutationresult.md)
+- [CreateQueryResult](type-aliases/createqueryresult.md)
+- [DefinedCreateInfiniteQueryResult](type-aliases/definedcreateinfinitequeryresult.md)
+- [DefinedCreateQueryResult](type-aliases/definedcreatequeryresult.md)
+- [DefinedInitialDataInfiniteOptions](type-aliases/definedinitialdatainfiniteoptions.md)
+- [DefinedInitialDataOptions](type-aliases/definedinitialdataoptions.md)
+- [NonUndefinedGuard](type-aliases/nonundefinedguard.md)
+- [QueriesOptions](type-aliases/queriesoptions.md)
+- [QueriesResults](type-aliases/queriesresults.md)
+- [UndefinedInitialDataInfiniteOptions](type-aliases/undefinedinitialdatainfiniteoptions.md)
+- [UndefinedInitialDataOptions](type-aliases/undefinedinitialdataoptions.md)
+
+## Functions
+
+- [infiniteQueryOptions](functions/infinitequeryoptions.md)
+- [injectInfiniteQuery](functions/injectinfinitequery.md)
+- [injectIsFetching](functions/injectisfetching.md)
+- [injectIsMutating](functions/injectismutating.md)
+- [injectMutation](functions/injectmutation.md)
+- [injectMutationState](functions/injectmutationstate.md)
+- [injectQueries](functions/injectqueries.md)
+- [injectQuery](functions/injectquery.md)
+- [injectQueryClient](functions/injectqueryclient.md)
+- [provideAngularQuery](functions/provideangularquery.md)
+- [provideQueryClient](functions/providequeryclient.md)
+- [queryOptions](functions/queryoptions.md)
diff --git a/docs/zh-hans/framework/angular/reference/interfaces/basemutationnarrowing.md b/docs/zh-hans/framework/angular/reference/interfaces/basemutationnarrowing.md
new file mode 100644
index 00000000000..487b6d6f5a1
--- /dev/null
+++ b/docs/zh-hans/framework/angular/reference/interfaces/basemutationnarrowing.md
@@ -0,0 +1,98 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:02:49.568Z'
+id: BaseMutationNarrowing
+title: BaseMutationNarrowing
+---
+
+# Interface: BaseMutationNarrowing\
+
+## Type Parameters
+
+• **TData** = `unknown`
+
+• **TError** = `DefaultError`
+
+• **TVariables** = `unknown`
+
+• **TContext** = `unknown`
+
+## Properties
+
+### isError()
+
+```ts
+isError: (this) => this is CreateMutationResult, Object> & Object>;
+```
+
+#### Parameters
+
+• **this**: [`CreateMutationResult`](../type-aliases/createmutationresult.md)\<`TData`, `TError`, `TVariables`, `TContext`, `CreateStatusBasedMutationResult`\<`"error"` \| `"success"` \| `"pending"` \| `"idle"`, `TData`, `TError`, `TVariables`, `TContext`\>\>
+
+#### Returns
+
+`this is CreateMutationResult, Object> & Object>`
+
+#### Defined in
+
+[types.ts:248](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/types.ts#L248)
+
+---
+
+### isIdle()
+
+```ts
+isIdle: (this) => this is CreateMutationResult, Object> & Object>;
+```
+
+#### Parameters
+
+• **this**: [`CreateMutationResult`](../type-aliases/createmutationresult.md)\<`TData`, `TError`, `TVariables`, `TContext`, `CreateStatusBasedMutationResult`\<`"error"` \| `"success"` \| `"pending"` \| `"idle"`, `TData`, `TError`, `TVariables`, `TContext`\>\>
+
+#### Returns
+
+`this is CreateMutationResult, Object> & Object>`
+
+#### Defined in
+
+[types.ts:278](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/types.ts#L278)
+
+---
+
+### isPending()
+
+```ts
+isPending: (this) => this is CreateMutationResult, Object> & Object>;
+```
+
+#### Parameters
+
+• **this**: [`CreateMutationResult`](../type-aliases/createmutationresult.md)\<`TData`, `TError`, `TVariables`, `TContext`, `CreateStatusBasedMutationResult`\<`"error"` \| `"success"` \| `"pending"` \| `"idle"`, `TData`, `TError`, `TVariables`, `TContext`\>\>
+
+#### Returns
+
+`this is CreateMutationResult, Object> & Object>`
+
+#### Defined in
+
+[types.ts:263](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/types.ts#L263)
+
+---
+
+### isSuccess()
+
+```ts
+isSuccess: (this) => this is CreateMutationResult, Object> & Object>;
+```
+
+#### Parameters
+
+• **this**: [`CreateMutationResult`](../type-aliases/createmutationresult.md)\<`TData`, `TError`, `TVariables`, `TContext`, `CreateStatusBasedMutationResult`\<`"error"` \| `"success"` \| `"pending"` \| `"idle"`, `TData`, `TError`, `TVariables`, `TContext`\>\>
+
+#### Returns
+
+`this is CreateMutationResult, Object> & Object>`
+
+#### Defined in
+
+[types.ts:233](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/types.ts#L233)
diff --git a/docs/zh-hans/framework/angular/reference/interfaces/basequerynarrowing.md b/docs/zh-hans/framework/angular/reference/interfaces/basequerynarrowing.md
new file mode 100644
index 00000000000..9ccdeab0dc0
--- /dev/null
+++ b/docs/zh-hans/framework/angular/reference/interfaces/basequerynarrowing.md
@@ -0,0 +1,74 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:02:49.532Z'
+id: BaseQueryNarrowing
+title: BaseQueryNarrowing
+---
+
+# Interface: BaseQueryNarrowing\
+
+## Type Parameters
+
+• **TData** = `unknown`
+
+• **TError** = `DefaultError`
+
+## Properties
+
+### isError()
+
+```ts
+isError: (this) => this is CreateBaseQueryResult>;
+```
+
+#### Parameters
+
+• **this**: [`CreateBaseQueryResult`](../type-aliases/createbasequeryresult.md)\<`TData`, `TError`, `QueryObserverResult`\<`TData`, `TError`\>\>
+
+#### Returns
+
+`this is CreateBaseQueryResult>`
+
+#### Defined in
+
+[types.ts:75](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/types.ts#L75)
+
+---
+
+### isPending()
+
+```ts
+isPending: (this) => this is CreateBaseQueryResult>;
+```
+
+#### Parameters
+
+• **this**: [`CreateBaseQueryResult`](../type-aliases/createbasequeryresult.md)\<`TData`, `TError`, `QueryObserverResult`\<`TData`, `TError`\>\>
+
+#### Returns
+
+`this is CreateBaseQueryResult>`
+
+#### Defined in
+
+[types.ts:82](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/types.ts#L82)
+
+---
+
+### isSuccess()
+
+```ts
+isSuccess: (this) => this is CreateBaseQueryResult>;
+```
+
+#### Parameters
+
+• **this**: [`CreateBaseQueryResult`](../type-aliases/createbasequeryresult.md)\<`TData`, `TError`, `QueryObserverResult`\<`TData`, `TError`\>\>
+
+#### Returns
+
+`this is CreateBaseQueryResult>`
+
+#### Defined in
+
+[types.ts:68](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/types.ts#L68)
diff --git a/docs/zh-hans/framework/angular/reference/interfaces/createbasequeryoptions.md b/docs/zh-hans/framework/angular/reference/interfaces/createbasequeryoptions.md
new file mode 100644
index 00000000000..66b913b6683
--- /dev/null
+++ b/docs/zh-hans/framework/angular/reference/interfaces/createbasequeryoptions.md
@@ -0,0 +1,24 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:02:49.494Z'
+id: CreateBaseQueryOptions
+title: CreateBaseQueryOptions
+---
+
+# Interface: CreateBaseQueryOptions\
+
+## Extends
+
+- `QueryObserverOptions`\<`TQueryFnData`, `TError`, `TData`, `TQueryData`, `TQueryKey`\>
+
+## Type Parameters
+
+• **TQueryFnData** = `unknown`
+
+• **TError** = `DefaultError`
+
+• **TData** = `TQueryFnData`
+
+• **TQueryData** = `TQueryFnData`
+
+• **TQueryKey** _extends_ `QueryKey` = `QueryKey`
diff --git a/docs/zh-hans/framework/angular/reference/interfaces/createinfinitequeryoptions.md b/docs/zh-hans/framework/angular/reference/interfaces/createinfinitequeryoptions.md
new file mode 100644
index 00000000000..552cb10bb1a
--- /dev/null
+++ b/docs/zh-hans/framework/angular/reference/interfaces/createinfinitequeryoptions.md
@@ -0,0 +1,26 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:02:49.431Z'
+id: CreateInfiniteQueryOptions
+title: CreateInfiniteQueryOptions
+---
+
+# Interface: CreateInfiniteQueryOptions\
+
+## Extends
+
+- `OmitKeyof`\<`InfiniteQueryObserverOptions`\<`TQueryFnData`, `TError`, `TData`, `TQueryData`, `TQueryKey`, `TPageParam`\>, `"suspense"`\>
+
+## Type Parameters
+
+• **TQueryFnData** = `unknown`
+
+• **TError** = `DefaultError`
+
+• **TData** = `TQueryFnData`
+
+• **TQueryData** = `TQueryFnData`
+
+• **TQueryKey** _extends_ `QueryKey` = `QueryKey`
+
+• **TPageParam** = `unknown`
diff --git a/docs/zh-hans/framework/angular/reference/interfaces/createmutationoptions.md b/docs/zh-hans/framework/angular/reference/interfaces/createmutationoptions.md
new file mode 100644
index 00000000000..884be525fdf
--- /dev/null
+++ b/docs/zh-hans/framework/angular/reference/interfaces/createmutationoptions.md
@@ -0,0 +1,22 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:02:49.390Z'
+id: CreateMutationOptions
+title: CreateMutationOptions
+---
+
+# Interface: CreateMutationOptions\
+
+## Extends
+
+- `OmitKeyof`\<`MutationObserverOptions`\<`TData`, `TError`, `TVariables`, `TContext`\>, `"_defaulted"`\>
+
+## Type Parameters
+
+• **TData** = `unknown`
+
+• **TError** = `DefaultError`
+
+• **TVariables** = `void`
+
+• **TContext** = `unknown`
diff --git a/docs/zh-hans/framework/angular/reference/interfaces/createqueryoptions.md b/docs/zh-hans/framework/angular/reference/interfaces/createqueryoptions.md
new file mode 100644
index 00000000000..2fbb5728381
--- /dev/null
+++ b/docs/zh-hans/framework/angular/reference/interfaces/createqueryoptions.md
@@ -0,0 +1,22 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:02:49.336Z'
+id: CreateQueryOptions
+title: CreateQueryOptions
+---
+
+# Interface: CreateQueryOptions\
+
+## Extends
+
+- `OmitKeyof`\<[`CreateBaseQueryOptions`](createbasequeryoptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryFnData`, `TQueryKey`\>, `"suspense"`\>
+
+## Type Parameters
+
+• **TQueryFnData** = `unknown`
+
+• **TError** = `DefaultError`
+
+• **TData** = `TQueryFnData`
+
+• **TQueryKey** _extends_ `QueryKey` = `QueryKey`
diff --git a/docs/zh-hans/framework/angular/reference/interfaces/injectmutationstateoptions.md b/docs/zh-hans/framework/angular/reference/interfaces/injectmutationstateoptions.md
new file mode 100644
index 00000000000..4e8c8f9ce6a
--- /dev/null
+++ b/docs/zh-hans/framework/angular/reference/interfaces/injectmutationstateoptions.md
@@ -0,0 +1,20 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:02:49.273Z'
+id: InjectMutationStateOptions
+title: InjectMutationStateOptions
+---
+
+# Interface: InjectMutationStateOptions
+
+## Properties
+
+### injector?
+
+```ts
+optional injector: Injector;
+```
+
+#### Defined in
+
+[inject-mutation-state.ts:43](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/inject-mutation-state.ts#L43)
diff --git a/docs/zh-hans/framework/angular/reference/type-aliases/createbasemutationresult.md b/docs/zh-hans/framework/angular/reference/type-aliases/createbasemutationresult.md
new file mode 100644
index 00000000000..b0e3c1580f5
--- /dev/null
+++ b/docs/zh-hans/framework/angular/reference/type-aliases/createbasemutationresult.md
@@ -0,0 +1,34 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:03:18.487Z'
+id: CreateBaseMutationResult
+title: CreateBaseMutationResult
+---
+
+# Type Alias: CreateBaseMutationResult\
+
+```ts
+type CreateBaseMutationResult: Override, object> & object;
+```
+
+## Type declaration
+
+### mutateAsync
+
+```ts
+mutateAsync: CreateMutateAsyncFunction
+```
+
+## Type Parameters
+
+• **TData** = `unknown`
+
+• **TError** = `DefaultError`
+
+• **TVariables** = `unknown`
+
+• **TContext** = `unknown`
+
+## Defined in
+
+[types.ts:198](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/types.ts#L198)
diff --git a/docs/zh-hans/framework/angular/reference/type-aliases/createbasequeryresult.md b/docs/zh-hans/framework/angular/reference/type-aliases/createbasequeryresult.md
new file mode 100644
index 00000000000..d62b9cbe05f
--- /dev/null
+++ b/docs/zh-hans/framework/angular/reference/type-aliases/createbasequeryresult.md
@@ -0,0 +1,24 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:03:18.445Z'
+id: CreateBaseQueryResult
+title: CreateBaseQueryResult
+---
+
+# Type Alias: CreateBaseQueryResult\
+
+```ts
+type CreateBaseQueryResult: BaseQueryNarrowing & MapToSignals>;
+```
+
+## Type Parameters
+
+• **TData** = `unknown`
+
+• **TError** = `DefaultError`
+
+• **TState** = `QueryObserverResult`\<`TData`, `TError`\>
+
+## Defined in
+
+[types.ts:116](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/types.ts#L116)
diff --git a/docs/zh-hans/framework/angular/reference/type-aliases/createinfinitequeryresult.md b/docs/zh-hans/framework/angular/reference/type-aliases/createinfinitequeryresult.md
new file mode 100644
index 00000000000..6b8232f92e1
--- /dev/null
+++ b/docs/zh-hans/framework/angular/reference/type-aliases/createinfinitequeryresult.md
@@ -0,0 +1,22 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:03:18.402Z'
+id: CreateInfiniteQueryResult
+title: CreateInfiniteQueryResult
+---
+
+# Type Alias: CreateInfiniteQueryResult\
+
+```ts
+type CreateInfiniteQueryResult: MapToSignals>;
+```
+
+## Type Parameters
+
+• **TData** = `unknown`
+
+• **TError** = `DefaultError`
+
+## Defined in
+
+[types.ts:143](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/types.ts#L143)
diff --git a/docs/zh-hans/framework/angular/reference/type-aliases/createmutateasyncfunction.md b/docs/zh-hans/framework/angular/reference/type-aliases/createmutateasyncfunction.md
new file mode 100644
index 00000000000..9020dbbe714
--- /dev/null
+++ b/docs/zh-hans/framework/angular/reference/type-aliases/createmutateasyncfunction.md
@@ -0,0 +1,26 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:03:18.361Z'
+id: CreateMutateAsyncFunction
+title: CreateMutateAsyncFunction
+---
+
+# Type Alias: CreateMutateAsyncFunction\
+
+```ts
+type CreateMutateAsyncFunction: MutateFunction;
+```
+
+## Type Parameters
+
+• **TData** = `unknown`
+
+• **TError** = `DefaultError`
+
+• **TVariables** = `void`
+
+• **TContext** = `unknown`
+
+## Defined in
+
+[types.ts:188](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/types.ts#L188)
diff --git a/docs/zh-hans/framework/angular/reference/type-aliases/createmutatefunction.md b/docs/zh-hans/framework/angular/reference/type-aliases/createmutatefunction.md
new file mode 100644
index 00000000000..f62f32d1dc1
--- /dev/null
+++ b/docs/zh-hans/framework/angular/reference/type-aliases/createmutatefunction.md
@@ -0,0 +1,34 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:03:18.324Z'
+id: CreateMutateFunction
+title: CreateMutateFunction
+---
+
+# Type Alias: CreateMutateFunction()\
+
+```ts
+type CreateMutateFunction: (...args) => void;
+```
+
+## Type Parameters
+
+• **TData** = `unknown`
+
+• **TError** = `DefaultError`
+
+• **TVariables** = `void`
+
+• **TContext** = `unknown`
+
+## Parameters
+
+• ...**args**: `Parameters`\<`MutateFunction`\<`TData`, `TError`, `TVariables`, `TContext`\>\>
+
+## Returns
+
+`void`
+
+## Defined in
+
+[types.ts:176](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/types.ts#L176)
diff --git a/docs/zh-hans/framework/angular/reference/type-aliases/createmutationresult.md b/docs/zh-hans/framework/angular/reference/type-aliases/createmutationresult.md
new file mode 100644
index 00000000000..06e175f805a
--- /dev/null
+++ b/docs/zh-hans/framework/angular/reference/type-aliases/createmutationresult.md
@@ -0,0 +1,28 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:03:18.291Z'
+id: CreateMutationResult
+title: CreateMutationResult
+---
+
+# Type Alias: CreateMutationResult\
+
+```ts
+type CreateMutationResult: BaseMutationNarrowing & MapToSignals>;
+```
+
+## Type Parameters
+
+• **TData** = `unknown`
+
+• **TError** = `DefaultError`
+
+• **TVariables** = `unknown`
+
+• **TContext** = `unknown`
+
+• **TState** = `CreateStatusBasedMutationResult`\<[`CreateBaseMutationResult`](createbasemutationresult.md)\[`"status"`\], `TData`, `TError`, `TVariables`, `TContext`\>
+
+## Defined in
+
+[types.ts:292](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/types.ts#L292)
diff --git a/docs/zh-hans/framework/angular/reference/type-aliases/createqueryresult.md b/docs/zh-hans/framework/angular/reference/type-aliases/createqueryresult.md
new file mode 100644
index 00000000000..b56b6830688
--- /dev/null
+++ b/docs/zh-hans/framework/angular/reference/type-aliases/createqueryresult.md
@@ -0,0 +1,22 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:03:18.245Z'
+id: CreateQueryResult
+title: CreateQueryResult
+---
+
+# Type Alias: CreateQueryResult\
+
+```ts
+type CreateQueryResult: CreateBaseQueryResult;
+```
+
+## Type Parameters
+
+• **TData** = `unknown`
+
+• **TError** = `DefaultError`
+
+## Defined in
+
+[types.ts:126](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/types.ts#L126)
diff --git a/docs/zh-hans/framework/angular/reference/type-aliases/definedcreateinfinitequeryresult.md b/docs/zh-hans/framework/angular/reference/type-aliases/definedcreateinfinitequeryresult.md
new file mode 100644
index 00000000000..1753cd2401b
--- /dev/null
+++ b/docs/zh-hans/framework/angular/reference/type-aliases/definedcreateinfinitequeryresult.md
@@ -0,0 +1,24 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:03:18.202Z'
+id: DefinedCreateInfiniteQueryResult
+title: DefinedCreateInfiniteQueryResult
+---
+
+# Type Alias: DefinedCreateInfiniteQueryResult\
+
+```ts
+type DefinedCreateInfiniteQueryResult: MapToSignals;
+```
+
+## Type Parameters
+
+• **TData** = `unknown`
+
+• **TError** = `DefaultError`
+
+• **TDefinedInfiniteQueryObserver** = `DefinedInfiniteQueryObserverResult`\<`TData`, `TError`\>
+
+## Defined in
+
+[types.ts:151](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/types.ts#L151)
diff --git a/docs/zh-hans/framework/angular/reference/type-aliases/definedcreatequeryresult.md b/docs/zh-hans/framework/angular/reference/type-aliases/definedcreatequeryresult.md
new file mode 100644
index 00000000000..e73bb0d6531
--- /dev/null
+++ b/docs/zh-hans/framework/angular/reference/type-aliases/definedcreatequeryresult.md
@@ -0,0 +1,24 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:03:18.165Z'
+id: DefinedCreateQueryResult
+title: DefinedCreateQueryResult
+---
+
+# Type Alias: DefinedCreateQueryResult\
+
+```ts
+type DefinedCreateQueryResult: MapToSignals;
+```
+
+## Type Parameters
+
+• **TData** = `unknown`
+
+• **TError** = `DefaultError`
+
+• **TDefinedQueryObserver** = `DefinedQueryObserverResult`\<`TData`, `TError`\>
+
+## Defined in
+
+[types.ts:134](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/types.ts#L134)
diff --git a/docs/zh-hans/framework/angular/reference/type-aliases/definedinitialdatainfiniteoptions.md b/docs/zh-hans/framework/angular/reference/type-aliases/definedinitialdatainfiniteoptions.md
new file mode 100644
index 00000000000..252ca425bb1
--- /dev/null
+++ b/docs/zh-hans/framework/angular/reference/type-aliases/definedinitialdatainfiniteoptions.md
@@ -0,0 +1,36 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:03:18.128Z'
+id: DefinedInitialDataInfiniteOptions
+title: DefinedInitialDataInfiniteOptions
+---
+
+# Type Alias: DefinedInitialDataInfiniteOptions\
+
+```ts
+type DefinedInitialDataInfiniteOptions: CreateInfiniteQueryOptions & object;
+```
+
+## Type declaration
+
+### initialData
+
+```ts
+initialData: NonUndefinedGuard> | () => NonUndefinedGuard>;
+```
+
+## Type Parameters
+
+• **TQueryFnData**
+
+• **TError** = `DefaultError`
+
+• **TData** = `InfiniteData`\<`TQueryFnData`\>
+
+• **TQueryKey** _extends_ `QueryKey` = `QueryKey`
+
+• **TPageParam** = `unknown`
+
+## Defined in
+
+[infinite-query-options.ts:32](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/infinite-query-options.ts#L32)
diff --git a/docs/zh-hans/framework/angular/reference/type-aliases/definedinitialdataoptions.md b/docs/zh-hans/framework/angular/reference/type-aliases/definedinitialdataoptions.md
new file mode 100644
index 00000000000..9d2f1d23bd8
--- /dev/null
+++ b/docs/zh-hans/framework/angular/reference/type-aliases/definedinitialdataoptions.md
@@ -0,0 +1,34 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:03:18.081Z'
+id: DefinedInitialDataOptions
+title: DefinedInitialDataOptions
+---
+
+# Type Alias: DefinedInitialDataOptions\
+
+```ts
+type DefinedInitialDataOptions: CreateQueryOptions & object;
+```
+
+## Type declaration
+
+### initialData
+
+```ts
+initialData: NonUndefinedGuard | () => NonUndefinedGuard;
+```
+
+## Type Parameters
+
+• **TQueryFnData** = `unknown`
+
+• **TError** = `DefaultError`
+
+• **TData** = `TQueryFnData`
+
+• **TQueryKey** _extends_ `QueryKey` = `QueryKey`
+
+## Defined in
+
+[query-options.ts:19](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/query-options.ts#L19)
diff --git a/docs/zh-hans/framework/angular/reference/type-aliases/nonundefinedguard.md b/docs/zh-hans/framework/angular/reference/type-aliases/nonundefinedguard.md
new file mode 100644
index 00000000000..57bb866538b
--- /dev/null
+++ b/docs/zh-hans/framework/angular/reference/type-aliases/nonundefinedguard.md
@@ -0,0 +1,20 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:03:18.042Z'
+id: NonUndefinedGuard
+title: NonUndefinedGuard
+---
+
+# Type Alias: NonUndefinedGuard\
+
+```ts
+type NonUndefinedGuard: T extends undefined ? never : T;
+```
+
+## Type Parameters
+
+• **T**
+
+## Defined in
+
+[types.ts:316](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/types.ts#L316)
diff --git a/docs/zh-hans/framework/angular/reference/type-aliases/queriesoptions.md b/docs/zh-hans/framework/angular/reference/type-aliases/queriesoptions.md
new file mode 100644
index 00000000000..628ebb19a09
--- /dev/null
+++ b/docs/zh-hans/framework/angular/reference/type-aliases/queriesoptions.md
@@ -0,0 +1,26 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:03:17.997Z'
+id: QueriesOptions
+title: QueriesOptions
+---
+
+# Type Alias: QueriesOptions\
+
+```ts
+type QueriesOptions: TDepth["length"] extends MAXIMUM_DEPTH ? QueryObserverOptionsForCreateQueries[] : T extends [] ? [] : T extends [infer Head] ? [...TResult, GetOptions] : T extends [infer Head, ...(infer Tail)] ? QueriesOptions<[...Tail], [...TResult, GetOptions], [...TDepth, 1]> : ReadonlyArray extends T ? T : T extends QueryObserverOptionsForCreateQueries[] ? QueryObserverOptionsForCreateQueries[] : QueryObserverOptionsForCreateQueries[];
+```
+
+QueriesOptions reducer recursively unwraps function arguments to infer/enforce type param
+
+## Type Parameters
+
+• **T** _extends_ `any`[]
+
+• **TResult** _extends_ `any`[] = []
+
+• **TDepth** _extends_ `ReadonlyArray`\<`number`\> = []
+
+## Defined in
+
+[inject-queries.ts:108](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/inject-queries.ts#L108)
diff --git a/docs/zh-hans/framework/angular/reference/type-aliases/queriesresults.md b/docs/zh-hans/framework/angular/reference/type-aliases/queriesresults.md
new file mode 100644
index 00000000000..962374fe49f
--- /dev/null
+++ b/docs/zh-hans/framework/angular/reference/type-aliases/queriesresults.md
@@ -0,0 +1,26 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:03:17.962Z'
+id: QueriesResults
+title: QueriesResults
+---
+
+# Type Alias: QueriesResults\
+
+```ts
+type QueriesResults: TDepth["length"] extends MAXIMUM_DEPTH ? QueryObserverResult[] : T extends [] ? [] : T extends [infer Head] ? [...TResult, GetResults] : T extends [infer Head, ...(infer Tail)] ? QueriesResults<[...Tail], [...TResult, GetResults], [...TDepth, 1]> : T extends QueryObserverOptionsForCreateQueries[] ? QueryObserverResult[] : QueryObserverResult[];
+```
+
+QueriesResults reducer recursively maps type param to results
+
+## Type Parameters
+
+• **T** _extends_ `any`[]
+
+• **TResult** _extends_ `any`[] = []
+
+• **TDepth** _extends_ `ReadonlyArray`\<`number`\> = []
+
+## Defined in
+
+[inject-queries.ts:151](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/inject-queries.ts#L151)
diff --git a/docs/zh-hans/framework/angular/reference/type-aliases/undefinedinitialdatainfiniteoptions.md b/docs/zh-hans/framework/angular/reference/type-aliases/undefinedinitialdatainfiniteoptions.md
new file mode 100644
index 00000000000..3d66a922419
--- /dev/null
+++ b/docs/zh-hans/framework/angular/reference/type-aliases/undefinedinitialdatainfiniteoptions.md
@@ -0,0 +1,36 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:03:17.913Z'
+id: UndefinedInitialDataInfiniteOptions
+title: UndefinedInitialDataInfiniteOptions
+---
+
+# Type Alias: UndefinedInitialDataInfiniteOptions\
+
+```ts
+type UndefinedInitialDataInfiniteOptions: CreateInfiniteQueryOptions & object;
+```
+
+## Type declaration
+
+### initialData?
+
+```ts
+optional initialData: undefined;
+```
+
+## Type Parameters
+
+• **TQueryFnData**
+
+• **TError** = `DefaultError`
+
+• **TData** = `InfiniteData`\<`TQueryFnData`\>
+
+• **TQueryKey** _extends_ `QueryKey` = `QueryKey`
+
+• **TPageParam** = `unknown`
+
+## Defined in
+
+[infinite-query-options.ts:12](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/infinite-query-options.ts#L12)
diff --git a/docs/zh-hans/framework/angular/reference/type-aliases/undefinedinitialdataoptions.md b/docs/zh-hans/framework/angular/reference/type-aliases/undefinedinitialdataoptions.md
new file mode 100644
index 00000000000..3d49d27cf86
--- /dev/null
+++ b/docs/zh-hans/framework/angular/reference/type-aliases/undefinedinitialdataoptions.md
@@ -0,0 +1,34 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:03:17.860Z'
+id: UndefinedInitialDataOptions
+title: UndefinedInitialDataOptions
+---
+
+# Type Alias: UndefinedInitialDataOptions\
+
+```ts
+type UndefinedInitialDataOptions: CreateQueryOptions & object;
+```
+
+## Type declaration
+
+### initialData?
+
+```ts
+optional initialData: undefined;
+```
+
+## Type Parameters
+
+• **TQueryFnData** = `unknown`
+
+• **TError** = `DefaultError`
+
+• **TData** = `TQueryFnData`
+
+• **TQueryKey** _extends_ `QueryKey` = `QueryKey`
+
+## Defined in
+
+[query-options.ts:7](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/angular-query-experimental/src/query-options.ts#L7)
diff --git a/docs/zh-hans/framework/angular/typescript.md b/docs/zh-hans/framework/angular/typescript.md
new file mode 100644
index 00000000000..b038e4b0b9b
--- /dev/null
+++ b/docs/zh-hans/framework/angular/typescript.md
@@ -0,0 +1,293 @@
+---
+source-updated-at: '2024-11-20T12:58:00.000Z'
+translation-updated-at: '2025-05-06T04:55:35.083Z'
+id: typescript
+title: TypeScript
+---
+
+TanStack Query 现已采用 **TypeScript** 编写,确保库与您的项目具备类型安全!
+
+注意事项:
+
+- 当前类型系统要求使用 TypeScript **v4.7** 或更高版本
+- 本仓库中的类型变更视为**非破坏性变更**,通常以 **patch** 版本号发布(否则每个类型增强都会导致主版本号变更!)
+- **强烈建议您将 angular-query-experimental 包版本锁定到特定 patch 版本**,并在升级时预期类型可能在任意版本间被修复或升级
+- TanStack Query 的非类型相关公共 API 及实验阶段结束后的 angular-query 包仍严格遵循语义化版本规范
+
+## 类型推断
+
+TanStack Query 的类型系统通常能完美流转,您无需自行添加类型注解
+
+```angular-ts
+@Component({
+ // ...
+ template: `@let data = query.data();`,
+ // ^? data: number | undefined
+})
+class MyComponent {
+ query = injectQuery(() => ({
+ queryKey: ['test'],
+ queryFn: () => Promise.resolve(5),
+ }))
+}
+```
+
+```angular-ts
+@Component({
+ // ...
+ template: `@let data = query.data();`,
+ // ^? data: string | undefined
+})
+class MyComponent {
+ query = injectQuery(() => ({
+ queryKey: ['test'],
+ queryFn: () => Promise.resolve(5),
+ select: (data) => data.toString(),
+ }))
+}
+```
+
+当您的 `queryFn` 具有明确定义的返回类型时效果最佳。请注意大多数数据获取库默认返回 `any` 类型,因此请确保将其提取到具有正确类型的函数中。
+
+以下示例中我们将 Group[] 传递给 HttpClient `get` 方法的类型参数:
+
+```angular-ts
+@Component({
+ template: `@let data = query.data();`,
+ // ^? data: Group[] | undefined
+})
+class MyComponent {
+ http = inject(HttpClient)
+
+ query = injectQuery(() => ({
+ queryKey: ['groups'],
+ queryFn: () => lastValueFrom(this.http.get('/groups')),
+ }))
+}
+```
+
+## 类型收窄
+
+TanStack Query 使用[可辨识联合类型](https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes-func.html#discriminated-unions)作为查询结果,通过 `status` 字段和派生的状态布尔值进行区分。这允许您检查如 `isSuccess()` 状态来确保 `data` 已定义:
+
+```angular-ts
+@Component({
+ // ...
+ template: `
+ @if (query.isSuccess()) {
+ @let data = query.data();
+ // ^? data: number
+ }
+ `,
+})
+class MyComponent {
+ query = injectQuery(() => ({
+ queryKey: ['test'],
+ queryFn: () => Promise.resolve(5),
+ }))
+}
+```
+
+> TypeScript 当前不支持对象方法的可辨识联合。在如查询结果这样的对象上对信号字段进行类型收窄仅适用于返回布尔值的信号。建议优先使用 `isSuccess()` 等布尔状态信号而非 `status() === 'success'`。
+
+## 错误字段类型标注
+
+错误类型默认为 `Error`,因为这符合大多数用户的预期:
+
+```angular-ts
+@Component({
+ // ...
+ template: `@let error = query.error();`,
+ // ^? error: Error | null
+})
+class MyComponent {
+ query = injectQuery(() => ({
+ queryKey: ['groups'],
+ queryFn: fetchGroups
+ }))
+}
+```
+
+如需抛出自定义错误或非 `Error` 对象,可指定错误字段类型:
+
+```angular-ts
+@Component({
+ // ...
+ template: `@let error = query.error();`,
+ // ^? error: string | null
+})
+class MyComponent {
+ query = injectQuery(() => ({
+ queryKey: ['groups'],
+ queryFn: fetchGroups,
+ }))
+}
+```
+
+但此方法会导致 `injectQuery` 其他泛型参数的类型推断失效。通常不建议抛出非 `Error` 对象,若您有如 `AxiosError` 的子类,可使用类型收窄使错误字段更具体:
+
+```ts
+import axios from 'axios'
+
+query = injectQuery(() => ({ queryKey: ['groups'], queryFn: fetchGroups }))
+
+computed(() => {
+ const error = query.error()
+ // ^? error: Error | null
+
+ if (axios.isAxiosError(error)) {
+ error
+ // ^? const error: AxiosError
+ }
+})
+```
+
+### 注册全局错误类型
+
+TanStack Query v5 支持通过扩展 `Register` 接口设置全局错误类型,无需在调用处指定泛型参数,同时保证类型推断仍有效:
+
+```ts
+import '@tanstack/angular-query-experimental'
+
+declare module '@tanstack/angular-query-experimental' {
+ interface Register {
+ defaultError: AxiosError
+ }
+}
+
+const query = injectQuery(() => ({
+ queryKey: ['groups'],
+ queryFn: fetchGroups,
+}))
+
+computed(() => {
+ const error = query.error()
+ // ^? error: AxiosError | null
+})
+```
+
+## 元数据 (meta) 类型标注
+
+### 注册全局元数据类型
+
+类似于注册[全局错误类型](#registering-a-global-error),您也可以注册全局 `Meta` 类型。这确保[查询](./reference/injectQuery.md)和[变更](./reference/injectMutation.md)中的可选 `meta` 字段保持类型安全且一致。注意注册类型必须扩展 `Record` 以保证 `meta` 始终为对象。
+
+```ts
+import '@tanstack/angular-query-experimental'
+
+interface MyMeta extends Record {
+ // 您的元类型定义
+}
+
+declare module '@tanstack/angular-query-experimental' {
+ interface Register {
+ queryMeta: MyMeta
+ mutationMeta: MyMeta
+ }
+}
+```
+
+## 查询与变更键 (key) 类型标注
+
+### 注册查询与变更键类型
+
+同样类似于注册[全局错误类型](#registering-a-global-error),您可注册全局 `QueryKey` 和 `MutationKey` 类型。这允许您为键提供更符合应用层次结构的类型约束,并在整个库中保持类型安全。注意注册类型必须扩展 `Array` 类型以保证键始终为数组。
+
+```ts
+import '@tanstack/angular-query-experimental'
+
+type QueryKey = ['dashboard' | 'marketing', ...ReadonlyArray]
+
+declare module '@tanstack/angular-query-experimental' {
+ interface Register {
+ queryKey: QueryKey
+ mutationKey: QueryKey
+ }
+}
+```
+
+## 查询选项 (Query Options) 类型标注
+
+若在 `injectQuery` 内联查询选项,将获得自动类型推断。但若需将查询选项提取到独立函数中以在 `injectQuery` 和 `prefetchQuery` 间共享,或将其托管在服务中,则会丢失类型推断。此时可使用 `queryOptions` 辅助工具恢复类型推断:
+
+```ts
+@Injectable({
+ providedIn: 'root',
+})
+export class QueriesService {
+ private http = inject(HttpClient)
+
+ post(postId: number) {
+ return queryOptions({
+ queryKey: ['post', postId],
+ queryFn: () => {
+ return lastValueFrom(
+ this.http.get(
+ `https://jsonplaceholder.typicode.com/posts/${postId}`,
+ ),
+ )
+ },
+ })
+ }
+}
+
+@Component({
+ // ...
+})
+export class Component {
+ queryClient = inject(QueryClient)
+
+ postId = signal(1)
+
+ queries = inject(QueriesService)
+ optionsSignal = computed(() => this.queries.post(this.postId()))
+
+ postQuery = injectQuery(() => this.queries.post(1))
+ postQuery = injectQuery(() => this.queries.post(this.postId()))
+
+ // 也可传递返回查询选项的信号
+ postQuery = injectQuery(this.optionsSignal)
+
+ someMethod() {
+ this.queryClient.prefetchQuery(this.queries.post(23))
+ }
+}
+```
+
+此外,`queryOptions` 返回的 `queryKey` 知晓其关联的 `queryFn`,我们可以利用此类型信息使如 `queryClient.getQueryData` 等方法也能感知这些类型:
+
+```ts
+data = this.queryClient.getQueryData(groupOptions().queryKey)
+// ^? data: Post | undefined
+```
+
+若不使用 `queryOptions`,data 类型将为 unknown,除非传递类型参数:
+
+```ts
+data = queryClient.getQueryData(['post', 1])
+```
+
+## 变更选项 (Mutation Options) 类型标注
+
+类似于 `queryOptions`,您可使用 `mutationOptions` 将变更选项提取到独立函数:
+
+```ts
+export class QueriesService {
+ private http = inject(HttpClient)
+
+ updatePost(id: number) {
+ return mutationOptions({
+ mutationFn: (post: Post) => Promise.resolve(post),
+ mutationKey: ['updatePost', id],
+ onSuccess: (newPost) => {
+ // ^? newPost: Post
+ this.queryClient.setQueryData(['posts', id], newPost)
+ },
+ })
+ }
+}
+```
+
+## 使用 `skipToken` 实现类型安全的查询禁用
+
+若使用 TypeScript,可通过 `skipToken` 禁用查询。这在需要基于条件禁用查询但仍需保持类型安全时非常有用。更多信息请参阅[禁用查询](./guides/disabling-queries.md)指南。
diff --git a/docs/zh-hans/framework/angular/zoneless.md b/docs/zh-hans/framework/angular/zoneless.md
new file mode 100644
index 00000000000..fd2899ec21c
--- /dev/null
+++ b/docs/zh-hans/framework/angular/zoneless.md
@@ -0,0 +1,13 @@
+---
+source-updated-at: '2024-06-20T22:57:31.000Z'
+translation-updated-at: '2025-05-06T04:49:56.860Z'
+id: zoneless
+title: 无 Zone
+---
+
+由于 TanStack Query 的 Angular 适配器基于信号机制构建,因此它能完全支持无区域(Zoneless)模式!
+
+无区域模式的优势包括提升性能和改进调试体验。具体细节请参阅 [Angular 官方文档](https://angular.dev/guide/experimental/zoneless)。
+
+> 请注意,Angular 无区域模式的 API 目前仍处于实验阶段,可能会在 Angular 的补丁版本中发生变更。
+> 除无区域模式外,该适配器同样完整支持 ZoneJS 变更检测。
diff --git a/docs/zh-hans/framework/react/community/community-projects.md b/docs/zh-hans/framework/react/community/community-projects.md
new file mode 100644
index 00000000000..2ae58b6513a
--- /dev/null
+++ b/docs/zh-hans/framework/react/community/community-projects.md
@@ -0,0 +1,161 @@
+---
+source-updated-at: '2025-03-30T12:50:39.000Z'
+translation-updated-at: '2025-05-06T03:59:00.632Z'
+id: community-projects
+title: 社区项目
+---
+
+有许多社区项目基于 React Query 构建,并利用它提供额外功能或增强开发者体验。以下项目按字母顺序排列。如果您有希望添加到列表中的项目,请提交 PR!
+
+> 请注意,这些项目完全由社区维护。如有相关问题,请联系项目维护者。
+
+## Atomic CRM
+
+一款功能齐全的 CRM,基于 React、react-admin 和 Supabase 构建。
+
+链接:https://marmelab.com/atomic-crm/
+
+## batshit
+
+批处理管理器,可对指定时间窗口内相同数据类型的请求进行去重和批量处理
+
+链接:https://github.com/yornaath/batshit
+
+## Blitz
+
+Next.js 的全栈工具包
+
+链接:https://blitzjs.com/
+
+## Connect
+
+用于构建浏览器兼容和 gRPC 兼容 HTTP API 的系列库
+
+链接:https://connectrpc.com/docs
+
+## GraphQL Code Generator
+
+根据 GraphQL 模式生成 React Query 钩子
+
+链接:https://the-guild.dev/graphql/codegen
+
+## Http-wizard
+
+✨ 基于 Fastify 的端到端类型安全 API,搭配 TypeScript 魔法 ✨
+
+链接:https://http-wizard.com
+
+## Kubb
+
+为所有 API 生成 SDK
+
+链接:https://www.kubb.dev/
+
+## NgQuery
+
+Angular 的查询适配器
+
+链接:https://ngneat.github.io/query/
+
+## Normy
+
+为数据获取库提供自动标准化和数据更新
+
+链接:https://github.com/klis87/normy
+
+## OpenAPI codegen
+
+基于 OpenAPI 模式生成代码的工具
+
+链接:https://github.com/fabien0102/openapi-codegen
+
+## OpenAPI Qraft React
+
+直接从 OpenAPI 文档生成类型安全的 API 客户端和 TanStack Query 钩子。
+零运行时开销、基于代理的设计、无缝 SSR 支持,完整 TanStack Query 功能。
+
+链接:https://github.com/OpenAPI-Qraft/openapi-qraft
+
+## OpenAPI React Query codegen
+
+基于 OpenAPI 规范文件生成 TanStack Query 钩子
+
+链接:https://github.com/7nohe/openapi-react-query-codegen
+
+### OpenAPI zod client
+
+根据 OpenAPI 规范生成 zodios 客户端
+
+链接:https://github.com/astahmer/openapi-zod-client
+
+## openapi-fetch
+
+仅 2KB 的轻量类型安全 fetch 封装器,使用静态 TypeScript 类型推断且无需运行时检查
+
+链接:https://openapi-ts.dev/openapi-react-query/
+
+## Orval
+
+根据 OpenAPI 规范生成 TypeScript 客户端
+
+链接:https://orval.dev/
+
+## Query Key factory
+
+创建类型安全标准化查询键的库,适用于 `@tanstack/query` 的缓存管理
+
+链接:https://github.com/lukemorales/query-key-factory
+
+## Rapini
+
+🥬 OpenAPI 转 React Query(或 SWR)& Axios
+
+链接:https://github.com/rametta/rapini
+
+## React Query Kit
+
+🕊️ ReactQuery 工具包,使 ReactQuery 钩子可复用且类型安全
+
+链接:https://github.com/liaoliao666/react-query-kit
+
+## React Query Rewind
+
+开发期间实现状态时间旅行与可视化
+
+链接:https://reactqueryrewind.com/
+
+## React Query Swagger
+
+基于 Swagger API 定义生成 React Query 钩子
+
+链接:https://github.com/Shaddix/react-query-swagger
+
+## Suspensive React Query
+
+为 React Query 增强 Suspense 支持,实现更简单声明式的数据获取
+
+链接:https://suspensive.org/docs/react-query/motivation
+
+## tRPC
+
+轻松实现端到端类型安全 API
+
+链接:https://trpc.io/
+
+## ts-rest
+
+为新旧 API 提供渐进式可采用的类型安全方案
+
+链接:https://ts-rest.com/
+
+## wagmi
+
+基于 `@tanstack/react-query` 的以太坊 React 钩子
+
+链接:https://wagmi.sh/
+
+## zodios
+
+端到端类型安全 REST API 工具箱
+
+链接:https://www.zodios.org/
diff --git a/docs/zh-hans/framework/react/community/tkdodos-blog.md b/docs/zh-hans/framework/react/community/tkdodos-blog.md
new file mode 100644
index 00000000000..3cd65b76d64
--- /dev/null
+++ b/docs/zh-hans/framework/react/community/tkdodos-blog.md
@@ -0,0 +1,88 @@
+---
+source-updated-at: '2025-03-18T08:45:11.000Z'
+translation-updated-at: '2025-05-06T03:58:18.522Z'
+id: tkdodos-blog
+title: TkDodo 的博客
+---
+
+TanStack Query 的维护者 [TkDodo](https://bsky.app/profile/tkdodo.eu) 撰写了一系列关于该库使用与实践的博客文章。部分文章展示了通用最佳实践,但大多数内容都带有鲜明的个人观点。
+
+## [#1: 实战 React Query](https://tkdodo.eu/blog/practical-react-query)
+
+> 一篇超越官方文档的高级指南,涵盖实用技巧:解析默认配置(`staleTime` 与 `gcTime` 的区别)、保持服务端与客户端状态分离的理念、处理依赖项与创建自定义钩子,并深入剖析 `enabled` 选项的强大之处。[阅读全文...](https://tkdodo.eu/blog/practical-react-query)
+
+## [#2: React Query 数据转换](https://tkdodo.eu/blog/react-query-data-transformations)
+
+> 探索使用 React Query 实现数据转换的多种方案。从在 `queryFn` 中转换到运用 `select` 选项,本文对比了不同方法的优劣。[阅读全文...](https://tkdodo.eu/blog/react-query-data-transformations)
+
+## [#3: React Query 渲染优化](https://tkdodo.eu/blog/react-query-render-optimizations)
+
+> 当组件因 React Query 频繁重渲染时该如何应对?本文详解库内置的优化机制(如 `tracked queries` 避免 `isFetching` 触发渲染),并解析 `structural sharing` 的深层含义。[阅读全文...](https://tkdodo.eu/blog/react-query-render-optimizations)
+
+## [#4: React Query 状态检查](https://tkdodo.eu/blog/status-checks-in-react-query)
+
+> 通常我们会先检查 `isPending` 再判断 `isError`,但有时优先验证 `data` 是否存在更能提升用户体验。本文揭示错误的状态检查顺序如何带来负面影响。[阅读全文...](https://tkdodo.eu/blog/status-checks-in-react-query)
+
+## [#5: 测试 React Query](https://tkdodo.eu/blog/testing-react-query)
+
+> 除了官方文档的测试指南,本文提供额外技巧:关闭 `retries`、静默 `console` 等自定义钩子测试策略,并附赠基于 `mock-service-worker` 的[示例仓库](https://github.com/TkDodo/testing-react-query)(含成功/错误状态测试)。[阅读全文...](https://tkdodo.eu/blog/testing-react-query)
+
+## [#6: React Query 与 TypeScript](https://tkdodo.eu/blog/react-query-and-type-script)
+
+> 深度解析 TypeScript 泛型在 React Query 中的应用:如何利用类型推断避免显式声明 `useQuery`、处理 `unknown` 错误、实现类型收窄等高级技巧。[阅读全文...](https://tkdodo.eu/blog/react-query-and-type-script)
+
+## [#7: 在 React Query 中使用 WebSockets](https://tkdodo.eu/blog/using-web-sockets-with-react-query)
+
+> 逐步指导如何实现实时通知:涵盖事件订阅与全量数据推送两种模式,适配浏览器原生 WebSocket API、Firebase 及 GraphQL 订阅。[阅读全文...](https://tkdodo.eu/blog/using-web-sockets-with-react-query)
+
+## [#8: 高效的 React Query Key 设计](https://tkdodo.eu/blog/effective-react-query-keys)
+
+> 超越简单的字符串键值:当应用复杂度超越待办列表时,如何通过协同定位(co-location)与 Query Key 工厂实现高效管理。[阅读全文...](https://tkdodo.eu/blog/effective-react-query-keys)
+
+## [#8a: 活用 Query 函数上下文](https://tkdodo.eu/blog/leveraging-the-query-function-context)
+
+> 前文补充篇:探讨如何结合 Query 函数上下文与对象键值,为成长型应用提供极致安全性。[阅读全文...](https://tkdodo.eu/blog/leveraging-the-query-function-context)
+
+## [#9: React Query 中的占位与初始数据](https://tkdodo.eu/blog/placeholder-and-initial-data-in-react-query)
+
+> 对比占位数据(Placeholder Data)与初始数据(Initial Data)的异同,解析二者在替代加载动画、提升 UX 时的适用场景。[阅读全文...](https://tkdodo.eu/blog/placeholder-and-initial-data-in-react-query)
+
+## [#10: 将 React Query 作为状态管理器](https://tkdodo.eu/blog/react-query-as-a-state-manager)
+
+> 揭秘如何让 React Query 成为异步状态的单一数据源:理解其数据同步本质,掌握通过定制 `staleTime` 释放威力的方法。[阅读全文...](https://tkdodo.eu/blog/react-query-as-a-state-manager)
+
+## [#11: React Query 错误处理](https://tkdodo.eu/blog/react-query-error-handling)
+
+> 全面应对异步数据错误:从 error 属性、Error Boundaries 到 onError 回调,为"出错了"的场景构建防御体系。[阅读全文...](https://tkdodo.eu/blog/react-query-error-handling)
+
+## [#12: 精通 React Query 数据变更](https://tkdodo.eu/blog/mastering-mutations-in-react-query)
+
+> 深度解析数据变更(mutations):区分与查询(queries)的本质差异,比较 `mutate` 与 `mutateAsync`,实现查询与变更的联动。[阅读全文...](https://tkdodo.eu/blog/mastering-mutations-in-react-query)
+
+## [#13: React Query 离线策略](https://tkdodo.eu/blog/offline-react-query)
+
+> 移动端网络不可靠?本文详解 React Query 在离线状态下的多种应对方案。[阅读全文...](https://tkdodo.eu/blog/offline-react-query)
+
+## [#14: React Query 与表单处理](https://tkdodo.eu/blog/react-query-and-forms)
+
+> 模糊服务端与客户端状态的边界:展示两种集成方案,提供表单与 React Query 协同使用的实用技巧。[阅读全文...](https://tkdodo.eu/blog/react-query-and-forms)
+
+## [#15: React Query 常见问题解答](https://tkdodo.eu/blog/react-query-fa-qs)
+
+> 集中解答关于 React Query 的高频疑问。[阅读全文...](https://tkdodo.eu/blog/react-query-fa-qs)
+
+## [#16: React Query 邂逅 React Router](https://tkdodo.eu/blog/react-query-meets-react-router)
+
+> 当 Remix 和 React Router 革新数据加载时机,为何说它们与 React Query 是天作之合?[阅读全文...](https://tkdodo.eu/blog/react-query-meets-react-router)
+
+## [#17: 预填充查询缓存](https://tkdodo.eu/blog/seeding-the-query-cache)
+
+> 多管齐下减少加载动画:从服务端预取、路由预加载到通过 `setQueryData` 注入缓存数据。[阅读全文...](https://tkdodo.eu/blog/seeding-the-query-cache)
+
+## [#18: React Query 内部机制](https://tkdodo.eu/blog/inside-react-query)
+
+> 图解 React Query 架构:从框架无关的 Query Core 到特定框架适配器的通信原理。[阅读全文...](https://tkdodo.eu/blog/inside-react-query)
+
+## [#19: 类型安全的 React Query](https://tkdodo.eu/blog/type-safe-react-query)
+
+> "拥有类型"与"类型安全"存在本质差异。本文演示如何结合 TypeScript 实现最高级别的类型安全。[阅读全文...](https://tkdodo.eu/blog/type-safe-react-query)
diff --git a/docs/zh-hans/framework/react/comparison.md b/docs/zh-hans/framework/react/comparison.md
new file mode 100644
index 00000000000..577e17989d6
--- /dev/null
+++ b/docs/zh-hans/framework/react/comparison.md
@@ -0,0 +1,113 @@
+---
+source-updated-at: '2024-07-11T12:20:14.000Z'
+translation-updated-at: '2025-05-06T04:32:05.206Z'
+id: comparison
+title: 对比
+---
+
+> 本对比表格力求准确公正。若您使用过其中任一库并认为信息有待完善,欢迎通过页面底部的 "Edit this page on Github" 链接提交修改建议(需附说明或证据)。
+
+功能/能力说明:
+
+- ✅ 开箱即用,无需额外配置或代码
+- 🟡 支持,但需通过第三方或社区库实现
+- 🔶 官方支持且文档完备,但需用户自行编写实现代码
+- 🛑 无官方支持或文档
+
+| | React Query | SWR [_(官网)_][swr] | Apollo Client [_(官网)_][apollo] | RTK-Query [_(官网)_][rtk-query] | React Router [_(官网)_][react-router] |
+| ------------------------------------- | ---------------------------------------- | ----------------------------- | -------------------------------- | ------------------------------------ | ------------------------------------------------------------------------- |
+| GitHub 仓库/星标数 | [![][stars-react-query]][gh-react-query] | [![][stars-swr]][gh-swr] | [![][stars-apollo]][gh-apollo] | [![][stars-rtk-query]][gh-rtk-query] | [![][stars-react-router]][gh-react-router] |
+| 平台要求 | React | React | React, GraphQL | Redux | React |
+| 官方对比 | | (无) | (无) | [对比][rtk-query-comparison] | (无) |
+| 支持的查询语法 | Promise, REST, GraphQL | Promise, REST, GraphQL | GraphQL, 任意 (响应式变量) | Promise, REST, GraphQL | Promise, REST, GraphQL |
+| 支持的框架 | React | React | React + 其他 | 任意 | React |
+| 缓存策略 | 层级键值对 | 唯一键值对 | 规范化 Schema | 唯一键值对 | 嵌套路由 -> 值 |
+| 缓存键策略 | JSON | JSON | GraphQL 查询 | JSON | 路由路径 |
+| 缓存变更检测 | 深度比较键值(稳定序列化) | 深度比较键值(稳定序列化) | 深度比较键值(非稳定序列化) | 键值引用相等 (===) | 路由变更 |
+| 数据变更检测 | 深度比较 + 结构共享 | 深度比较 (通过 `stable-hash`) | 深度比较(非稳定序列化) | 键值引用相等 (===) | 加载器执行 |
+| 数据记忆化 | 完整结构共享 | 标识相等 (===) | 规范化标识 | 标识相等 (===) | 标识相等 (===) |
+| 包体积 | [![][bp-react-query]][bpl-react-query] | [![][bp-swr]][bpl-swr] | [![][bp-apollo]][bpl-apollo] | [![][bp-rtk-query]][bpl-rtk-query] | [![][bp-react-router]][bpl-react-router] + [![][bp-history]][bpl-history] |
+| API 定义位置 | 组件内,外部配置 | 组件内 | GraphQL Schema | 外部配置 | 路由树配置 |
+| 查询 | ✅ | ✅ | ✅ | ✅ | ✅ |
+| 缓存持久化 | ✅ | ✅ | ✅ | ✅ | 🛑 仅活跃路由 8 |
+| 开发者工具 | ✅ | ✅ | ✅ | ✅ | 🛑 |
+| 轮询/间隔查询 | ✅ | ✅ | ✅ | ✅ | 🛑 |
+| 并行查询 | ✅ | ✅ | ✅ | ✅ | ✅ |
+| 依赖查询 | ✅ | ✅ | ✅ | ✅ | ✅ |
+| 分页查询 | ✅ | ✅ | ✅ | ✅ | ✅ |
+| 无限查询 | ✅ | ✅ | ✅ | 🛑 | 🛑 |
+| 双向无限查询 | ✅ | 🔶 | 🔶 | 🛑 | 🛑 |
+| 无限查询重获取 | ✅ | ✅ | 🛑 | 🛑 | 🛑 |
+| 滞后查询数据1 | ✅ | ✅ | ✅ | ✅ | ✅ |
+| 选择器 | ✅ | 🛑 | ✅ | ✅ | N/A |
+| 初始数据 | ✅ | ✅ | ✅ | ✅ | ✅ |
+| 滚动恢复 | ✅ | ✅ | ✅ | ✅ | ✅ |
+| 缓存操作 | ✅ | ✅ | ✅ | ✅ | 🛑 |
+| 过时查询丢弃 | ✅ | ✅ | ✅ | ✅ | ✅ |
+| 渲染批处理与优化2 | ✅ | ✅ | 🛑 | ✅ | ✅ |
+| 自动垃圾回收 | ✅ | 🛑 | 🛑 | ✅ | N/A |
+| 变更钩子 | ✅ | ✅ | ✅ | ✅ | ✅ |
+| 离线变更支持 | ✅ | 🛑 | 🟡 | 🛑 | 🛑 |
+| 预获取 API | ✅ | ✅ | ✅ | ✅ | ✅ |
+| 查询取消 | ✅ | 🛑 | 🛑 | 🛑 | ✅ |
+| 部分查询匹配3 | ✅ | 🔶 | ✅ | ✅ | N/A |
+| 后台重新验证 (Stale While Revalidate) | ✅ | ✅ | ✅ | ✅ | 🛑 |
+| 过期时间配置 | ✅ | 🛑7 | 🛑 | ✅ | 🛑 |
+| 预使用查询/变更配置4 | ✅ | 🛑 | ✅ | ✅ | ✅ |
+| 窗口聚焦重获取 | ✅ | ✅ | 🛑 | ✅ | 🛑 |
+| 网络状态重获取 | ✅ | ✅ | ✅ | ✅ | 🛑 |
+| 通用缓存脱水/再水合 | ✅ | 🛑 | ✅ | ✅ | ✅ |
+| 离线缓存 | ✅ | 🛑 | ✅ | 🔶 | 🛑 |
+| React Suspense 支持 | ✅ | ✅ | ✅ | 🛑 | ✅ |
+| 抽象化/框架无关核心 | ✅ | 🛑 | ✅ | ✅ | 🛑 |
+| 变更后自动重获取5 | 🔶 | 🔶 | ✅ | ✅ | ✅ |
+| 规范化缓存6 | 🛑 | 🛑 | ✅ | 🛑 | 🛑 |
+
+### 注解
+
+> **1 滞后查询数据** - React Query 允许在加载新查询时继续显示现有查询数据(类似于 Suspense 即将原生提供的 UX)。这在编写分页 UI 或无限加载 UI 时至关重要,可避免每次请求新查询时出现生硬的加载状态。其他库不具备此能力,会在新查询加载时呈现生硬加载状态(除非已预获取)。
+
+> **2 渲染优化** - React Query 具有卓越的渲染性能。默认会跟踪访问字段,仅在这些字段变化时重新渲染。若需禁用此优化,将 `notifyOnChangeProps` 设为 `'all'` 会在查询更新时重新渲染组件(例如获取新数据时)。React Query 还会批量更新,确保多组件使用同一查询时应用仅重新渲染一次。若仅关注 `data` 或 `error` 属性,可通过设置 `notifyOnChangeProps` 为 `['data', 'error']` 进一步减少渲染次数。
+
+> **3 部分查询匹配** - 因 React Query 使用确定性查询键序列化,可操作变量组查询而无需知晓每个具体查询键。例如:可重新获取键以 `todos` 开头的所有查询(无论变量如何),或精准定位带(或不带)变量的特定查询,甚至使用过滤函数匹配符合特定条件的查询。
+
+> **4 预使用查询配置** - 指在查询/变更被使用前预先配置其行为的能力。例如:可预先为查询设置完整默认配置,使用时仅需 `useQuery({ queryKey })`,而无需每次传递获取器或选项。SWR 通过允许配置全局默认获取器部分实现此功能,但不支持按查询配置,也不支持变更操作。
+
+> **5 变更后自动重获取** - 要实现变更后真正自动重获取,需具备模式(如 GraphQL 提供的)及帮助库识别该模式中实体类型和单个实体的启发式方法。
+
+> **6 规范化缓存** - React Query、SWR 和 RTK-Query 目前不支持自动规范化缓存(即通过扁平化存储实体避免高层级数据重复)。
+
+> **7 SWR 的不可变模式** - SWR 提供 "immutable" 模式允许查询在缓存生命周期内仅获取一次,但仍不具备过期时间概念或有条件的自动重新验证能力。
+
+> **8 React Router 缓存持久化** - React Router 不会缓存当前匹配路由之外的数据。离开路由后,其数据即丢失。
+
+[bpl-react-query]: https://bundlephobia.com/result?p=react-query
+[bp-react-query]: https://badgen.net/bundlephobia/minzip/react-query?label=💾
+[gh-react-query]: https://github.com/tannerlinsley/react-query
+[stars-react-query]: https://img.shields.io/github/stars/tannerlinsley/react-query?label=%F0%9F%8C%9F
+[swr]: https://github.com/vercel/swr
+[bp-swr]: https://badgen.net/bundlephobia/minzip/swr?label=💾
+[gh-swr]: https://github.com/vercel/swr
+[stars-swr]: https://img.shields.io/github/stars/vercel/swr?label=%F0%9F%8C%9F
+[bpl-swr]: https://bundlephobia.com/result?p=swr
+[apollo]: https://github.com/apollographql/apollo-client
+[bp-apollo]: https://badgen.net/bundlephobia/minzip/@apollo/client?label=💾
+[gh-apollo]: https://github.com/apollographql/apollo-client
+[stars-apollo]: https://img.shields.io/github/stars/apollographql/apollo-client?label=%F0%9F%8C%9F
+[bpl-apollo]: https://bundlephobia.com/result?p=@apollo/client
+[rtk-query]: https://redux-toolkit.js.org/rtk-query/overview
+[rtk-query-comparison]: https://redux-toolkit.js.org/rtk-query/comparison
+[rtk-query-bundle-size]: https://redux-toolkit.js.org/rtk-query/comparison#bundle-size
+[bp-rtk]: https://badgen.net/bundlephobia/minzip/@reduxjs/toolkit?label=💾
+[bp-rtk-query]: https://badgen.net/bundlephobia/minzip/@reduxjs/toolkit?label=💾
+[gh-rtk-query]: https://github.com/reduxjs/redux-toolkit
+[stars-rtk-query]: https://img.shields.io/github/stars/reduxjs/redux-toolkit?label=🌟
+[bpl-rtk]: https://bundlephobia.com/result?p=@reduxjs/toolkit
+[bpl-rtk-query]: https://bundlephobia.com/package/@reduxjs/toolkit
+[react-router]: https://github.com/remix-run/react-router
+[bp-react-router]: https://badgen.net/bundlephobia/minzip/react-router-dom?label=💾
+[gh-react-router]: https://github.com/remix-run/react-router
+[stars-react-router]: https://img.shields.io/github/stars/remix-run/react-router?label=%F0%9F%8C%9F
+[bpl-react-router]: https://bundlephobia.com/result?p=react-router-dom
+[bp-history]: https://badgen.net/bundlephobia/minzip/history?label=💾
+[bpl-history]: https://bundlephobia.com/result?p=history
diff --git a/docs/zh-hans/framework/react/devtools.md b/docs/zh-hans/framework/react/devtools.md
new file mode 100644
index 00000000000..9a8e9ea28c3
--- /dev/null
+++ b/docs/zh-hans/framework/react/devtools.md
@@ -0,0 +1,198 @@
+---
+source-updated-at: '2024-11-04T06:38:47.000Z'
+translation-updated-at: '2025-05-06T04:27:37.043Z'
+id: devtools
+title: 开发者工具
+---
+
+# Devtools
+
+欢呼雀跃吧,因为 React Query 配备了专属开发者工具!🥳
+
+当你开始 React Query 之旅时,这些开发者工具将成为得力助手。它们能可视化 React Query 的内部运作机制,在你遇到棘手问题时,很可能为你节省数小时的调试时间!
+
+> 请注意:目前开发者工具 **暂不支持 React Native**。若您有意协助我们实现跨平台支持,请随时告知!
+
+> 激动消息:我们现已推出独立的 React Native React Query DevTools 包!这一新增功能提供原生支持,让你可以直接在 React Native 项目中集成开发者工具。立即查看并参与贡献:[react-native-react-query-devtools](https://github.com/LovesWorking/react-native-react-query-devtools)
+
+> 另有一款外部工具可通过仪表盘使用 React Query 开发者工具。了解更多并参与贡献:[react-query-external-sync](https://github.com/LovesWorking/react-query-external-sync)
+
+> 注意:自第 5 版起,开发者工具已支持观察变更 (mutations)。
+
+## 安装与导入开发者工具
+
+开发者工具是独立包,需单独安装:
+
+```bash
+npm i @tanstack/react-query-devtools
+```
+
+或
+
+```bash
+pnpm add @tanstack/react-query-devtools
+```
+
+或
+
+```bash
+yarn add @tanstack/react-query-devtools
+```
+
+或
+
+```bash
+bun add @tanstack/react-query-devtools
+```
+
+对于 Next 13+ App 目录,必须将其作为开发依赖安装才能正常工作。
+
+导入方式如下:
+
+```tsx
+import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
+```
+
+默认情况下,React Query 开发者工具仅在 `process.env.NODE_ENV === 'development'` 时包含在构建包中,因此无需担心生产环境构建时的排除问题。
+
+## 浮动模式
+
+浮动模式会将开发者工具作为固定浮动元素挂载在应用中,并在屏幕角落提供显示/隐藏开关。该开关状态会通过 localStorage 保存,并在页面刷新后保持记忆。
+
+请将以下代码尽可能放置在 React 应用的顶层。越接近页面根节点,效果越好!
+
+```tsx
+import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
+
+function App() {
+ return (
+
+ {/* 应用其他内容 */}
+
+
+ )
+}
+```
+
+### 配置项
+
+- `initialIsOpen: Boolean`
+ - 设为 `true` 可使开发者工具默认展开
+- `buttonPosition?: "top-left" | "top-right" | "bottom-left" | "bottom-right" | "relative"`
+ - 默认为 `bottom-right`
+ - 控制 React Query 徽标按钮的位置,用于展开/收起面板
+ - 设为 `relative` 时,按钮将出现在开发者工具的渲染位置
+- `position?: "top" | "bottom" | "left" | "right"`
+ - 默认为 `bottom`
+ - 开发者工具面板的展开位置
+- `client?: QueryClient`,
+ - 使用自定义 QueryClient。未指定时使用最近上下文中的实例
+- `errorTypes?: { name: string; initializer: (query: Query) => TError}[]`
+ - 预定义可触发的错误类型。当从 UI 切换错误时,初始化器(传入特定查询)将被调用,必须返回一个 Error 对象
+- `styleNonce?: string`
+ - 向文档头部的 style 标签传递 nonce 值,适用于需要内容安全策略 (CSP) nonce 的场景
+- `shadowDOMTarget?: ShadowRoot`
+ - 默认行为是将样式应用到 DOM 的 head 标签
+ - 传入 shadow DOM 目标可使样式在 shadow DOM 内生效而非 light DOM 的 head 标签
+
+## 嵌入式模式
+
+嵌入式模式将开发者工具作为固定元素显示在应用中,便于你在自有开发工具中使用我们的面板。
+
+请将以下代码尽可能放置在 React 应用的顶层:
+
+```tsx
+import { ReactQueryDevtoolsPanel } from '@tanstack/react-query-devtools'
+
+function App() {
+ const [isOpen, setIsOpen] = React.useState(false)
+
+ return (
+
+ {/* 应用其他内容 */}
+ setIsOpen(!isOpen)}
+ >{`${isOpen ? '关闭' : '打开'}开发者工具面板`}
+ {isOpen && setIsOpen(false)} />}
+
+ )
+}
+```
+
+### 配置项
+
+- `style?: React.CSSProperties`
+ - 面板自定义样式
+ - 默认值:`{ height: '500px' }`
+ - 示例:`{ height: '100%' }`
+ - 示例:`{ height: '100%', width: '100%' }`
+- `onClose?: () => unknown`
+ - 面板关闭时的回调函数
+- `client?: QueryClient`,
+ - 使用自定义 QueryClient。未指定时使用最近上下文中的实例
+- `errorTypes?: { name: string; initializer: (query: Query) => TError}[]`
+ - 预定义可触发的错误类型
+- `styleNonce?: string`
+ - 向文档头部 style 标签传递 nonce 值
+- `shadowDOMTarget?: ShadowRoot`
+ - 控制样式作用域为 shadow DOM 而非 light DOM
+
+## 生产环境使用开发者工具
+
+开发者工具默认排除在生产构建外。但可通过懒加载方式在生产环境使用:
+
+```tsx
+import * as React from 'react'
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
+import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
+import { Example } from './Example'
+
+const queryClient = new QueryClient()
+
+const ReactQueryDevtoolsProduction = React.lazy(() =>
+ import('@tanstack/react-query-devtools/build/modern/production.js').then(
+ (d) => ({
+ default: d.ReactQueryDevtools,
+ }),
+ ),
+)
+
+function App() {
+ const [showDevtools, setShowDevtools] = React.useState(false)
+
+ React.useEffect(() => {
+ // @ts-expect-error
+ window.toggleDevtools = () => setShowDevtools((old) => !old)
+ }, [])
+
+ return (
+
+
+
+ {showDevtools && (
+
+
+
+ )}
+
+ )
+}
+
+export default App
+```
+
+调用 `window.toggleDevtools()` 将下载开发者工具包并显示。
+
+### 现代打包工具
+
+若打包工具支持包导出,可使用以下导入路径:
+
+```tsx
+const ReactQueryDevtoolsProduction = React.lazy(() =>
+ import('@tanstack/react-query-devtools/production').then((d) => ({
+ default: d.ReactQueryDevtools,
+ })),
+)
+```
+
+TypeScript 用户需在 tsconfig 中设置 `moduleResolution: 'nodenext'`,这要求 TypeScript 版本至少为 v4.7。
diff --git a/docs/zh-hans/framework/react/graphql.md b/docs/zh-hans/framework/react/graphql.md
new file mode 100644
index 00000000000..2425c8172f4
--- /dev/null
+++ b/docs/zh-hans/framework/react/graphql.md
@@ -0,0 +1,57 @@
+---
+source-updated-at: '2024-01-25T20:57:22.000Z'
+translation-updated-at: '2025-05-06T04:24:54.134Z'
+id: graphql
+title: GraphQL
+---
+
+由于 React Query 的获取机制是基于 Promise 无感知构建的,你可以将 React Query 与任何异步数据获取客户端一起使用,包括 GraphQL!
+
+> 请注意,React Query 不支持规范化缓存。虽然绝大多数用户实际上并不需要规范化缓存,甚至从中获得的收益比他们想象的要少得多,但在极少数情况下可能需要它。因此,请务必先与我们确认,以确保这确实是您所需要的功能!
+
+[//]: # 'Codegen'
+
+## 类型安全与代码生成
+
+React Query 结合 `graphql-request^5` 和 [GraphQL Code Generator](https://graphql-code-generator.com/) 使用,可以提供完全类型化的 GraphQL 操作:
+
+```tsx
+import request from 'graphql-request'
+import { useQuery } from '@tanstack/react-query'
+
+import { graphql } from './gql/gql'
+
+const allFilmsWithVariablesQueryDocument = graphql(/* GraphQL */ `
+ query allFilmsWithVariablesQuery($first: Int!) {
+ allFilms(first: $first) {
+ edges {
+ node {
+ id
+ title
+ }
+ }
+ }
+ }
+`)
+
+function App() {
+ // `data` 是完全类型化的!
+ const { data } = useQuery({
+ queryKey: ['films'],
+ queryFn: async () =>
+ request(
+ 'https://swapi-graphql.netlify.app/.netlify/functions/index',
+ allFilmsWithVariablesQueryDocument,
+ // 变量也会进行类型检查!
+ { first: 10 },
+ ),
+ })
+ // ...
+}
+```
+
+_你可以在 [代码仓库中找到完整示例](https://github.com/dotansimha/graphql-code-generator/tree/7c25c4eeb77f88677fd79da557b7b5326e3f3950/examples/front-end/react/tanstack-react-query)_
+
+请参考 [GraphQL Code Generator 文档中的专用指南](https://www.the-guild.dev/graphql/codegen/docs/guides/react-vue) 开始使用。
+
+[//]: # 'Codegen'
diff --git a/docs/zh-hans/framework/react/guides/advanced-ssr.md b/docs/zh-hans/framework/react/guides/advanced-ssr.md
new file mode 100644
index 00000000000..57aeeecb1fd
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/advanced-ssr.md
@@ -0,0 +1,414 @@
+---
+source-updated-at: '2025-03-18T08:45:11.000Z'
+translation-updated-at: '2025-05-06T04:16:25.641Z'
+id: advanced-ssr
+title: 高级服务端渲染
+---
+
+欢迎阅读高级服务端渲染 (Advanced Server Rendering) 指南,这里您将全面了解如何在流式渲染、服务器组件 (Server Components) 和 Next.js 应用路由 (app router) 中使用 React Query。
+
+建议先阅读[服务端渲染与注水 (Server Rendering & Hydration)](./ssr.md) 指南了解 SSR 基础,以及[性能与请求瀑布流 (Performance & Request Waterfalls)](./request-waterfalls.md) 和[预取与路由集成 (Prefetching & Router Integration)](./prefetching.md) 获取背景知识。
+
+首先请注意,虽然 SSR 指南中提到的 `initialData` 方式也适用于服务器组件,但本指南将重点介绍注水 (hydration) API。
+
+## 服务器组件与 Next.js 应用路由
+
+我们不会深入探讨服务器组件,简而言之它们是**保证仅在服务端运行**的组件,既在初始页面加载时,也**在页面切换时**运行。这与 Next.js 的 `getServerSideProps`/`getStaticProps` 和 Remix 的 `loader` 类似,但服务器组件不仅能返回数据,还能执行更多操作。不过数据部分仍是 React Query 的核心关注点。
+
+如何将服务端渲染指南中[通过框架加载器预取数据](./ssr.md#using-the-hydration-apis)的知识应用到服务器组件和 Next.js 应用路由?最佳思路是将服务器组件视为"另一种"框架加载器。
+
+### 术语说明
+
+目前我们一直使用*服务端*和*客户端*这两个术语。需要注意的是,这与*服务器组件*和*客户端组件*并非一一对应。服务器组件保证只在服务端运行,但客户端组件实际上可以在两端运行,因为它们也会在初始*服务端渲染*阶段执行。
+
+可以理解为:服务器组件的渲染发生在"加载阶段"(始终在服务端),而客户端组件运行在"应用阶段"。这个应用阶段既可能在 SSR 时运行于服务端,也可能在浏览器中运行。具体运行位置和是否参与 SSR 取决于不同框架的实现。
+
+### 初始设置
+
+React Query 的第一步总是创建 `queryClient` 并用 `QueryClientProvider` 包裹应用。在服务器组件中的设置各框架大体相似,主要区别在于文件命名约定:
+
+```tsx
+// Next.js 中该文件名为: app/providers.tsx
+'use client'
+
+// 由于 QueryClientProvider 底层依赖 useContext,必须在顶部声明 'use client'
+import {
+ isServer,
+ QueryClient,
+ QueryClientProvider,
+} from '@tanstack/react-query'
+
+function makeQueryClient() {
+ return new QueryClient({
+ defaultOptions: {
+ queries: {
+ // SSR 时通常需要设置默认 staleTime
+ // 大于 0 以避免客户端立即重新获取
+ staleTime: 60 * 1000,
+ },
+ },
+ })
+}
+
+let browserQueryClient: QueryClient | undefined = undefined
+
+function getQueryClient() {
+ if (isServer) {
+ // 服务端:总是创建新 query client
+ return makeQueryClient()
+ } else {
+ // 浏览器:如果没有则创建新 query client
+ // 这非常重要,避免在初始渲染时 React 挂起导致重复创建
+ if (!browserQueryClient) browserQueryClient = makeQueryClient()
+ return browserQueryClient
+ }
+}
+
+export default function Providers({ children }: { children: React.ReactNode }) {
+ // 注意:如果没有 suspense 边界,应避免使用 useState 初始化 query client
+ // 因为 React 会在初始挂起渲染时丢弃该 client
+ const queryClient = getQueryClient()
+
+ return (
+ {children}
+ )
+}
+```
+
+```tsx
+// Next.js 中该文件名为: app/layout.tsx
+import Providers from './providers'
+
+export default function RootLayout({
+ children,
+}: {
+ children: React.ReactNode
+}) {
+ return (
+
+
+
+ {children}
+
+
+ )
+}
+```
+
+这与 SSR 指南中的做法非常相似,只是需要将代码拆分到两个文件中。
+
+### 数据预取与脱水/注水
+
+接下来看看如何在**Next.js 页面路由**中预取数据并进行脱水/注水:
+
+```tsx
+// pages/posts.tsx
+import {
+ dehydrate,
+ HydrationBoundary,
+ QueryClient,
+ useQuery,
+} from '@tanstack/react-query'
+
+// 这里也可以是 getServerSideProps
+export async function getStaticProps() {
+ const queryClient = new QueryClient()
+
+ await queryClient.prefetchQuery({
+ queryKey: ['posts'],
+ queryFn: getPosts,
+ })
+
+ return {
+ props: {
+ dehydratedState: dehydrate(queryClient),
+ },
+ }
+}
+
+function Posts() {
+ // 这个 useQuery 也可以放在 的深层子组件中
+ // 注意这里使用 useQuery 而非 useSuspenseQuery
+ const { data } = useQuery({ queryKey: ['posts'], queryFn: getPosts })
+
+ // 这个查询未在服务端预取,会在客户端才开始获取
+ const { data: commentsData } = useQuery({
+ queryKey: ['posts-comments'],
+ queryFn: getComments,
+ })
+
+ // ...
+}
+
+export default function PostsRoute({ dehydratedState }) {
+ return (
+
+
+
+ )
+}
+```
+
+转换为应用路由后代码非常相似,只需稍作调整。首先创建服务器组件处理预取:
+
+```tsx
+// app/posts/page.tsx
+import {
+ dehydrate,
+ HydrationBoundary,
+ QueryClient,
+} from '@tanstack/react-query'
+import Posts from './posts'
+
+export default async function PostsPage() {
+ const queryClient = new QueryClient()
+
+ await queryClient.prefetchQuery({
+ queryKey: ['posts'],
+ queryFn: getPosts,
+ })
+
+ return (
+ // 注:HydrationBoundary 是客户端组件,注水将在那里发生
+
+
+
+ )
+}
+```
+
+客户端组件部分如下:
+
+```tsx
+// app/posts/posts.tsx
+'use client'
+
+export default function Posts() {
+ // 这个 useQuery 也可以放在深层子组件中
+ const { data } = useQuery({
+ queryKey: ['posts'],
+ queryFn: () => getPosts(),
+ })
+
+ // 这个查询未在服务端预取,会在客户端才开始获取
+ const { data: commentsData } = useQuery({
+ queryKey: ['posts-comments'],
+ queryFn: getComments,
+ })
+
+ // ...
+}
+```
+
+这些示例的巧妙之处在于,除了文件名外其他代码在任何支持服务器组件的框架中都通用。
+
+在 SSR 指南中我们提到可以省略每个路由中的 `` 样板代码,但这在服务器组件中不可行。
+
+> 注意:如果在 TypeScript 低于 `5.1.3` 或 `@types/react` 低于 `18.2.8` 版本中使用异步服务器组件遇到类型错误,建议升级到最新版本。临时解决方案是在调用组件时添加 `{/* @ts-expect-error Server Component */}`。详见 Next.js 13 文档中的[异步服务器组件类型错误](https://nextjs.org/docs/app/building-your-application/configuring/typescript#async-server-component-typescript-error)。
+
+> 注意:如果遇到错误 `Only plain objects, and a few built-ins, can be passed to Server Actions. Classes or null prototypes are not supported.`,请确保没有向 queryFn 传递函数引用,而应调用函数,因为 queryFn 参数包含许多不可序列化的属性。参见[服务器操作仅在 queryFn 非引用时有效](https://github.com/TanStack/query/issues/6264)。
+
+### 嵌套服务器组件
+
+服务器组件的优势在于可以嵌套在 React 树的多个层级,使得数据预取更接近实际使用位置。简单示例如下(省略客户端组件):
+
+```tsx
+// app/posts/page.tsx
+import {
+ dehydrate,
+ HydrationBoundary,
+ QueryClient,
+} from '@tanstack/react-query'
+import Posts from './posts'
+import CommentsServerComponent from './comments-server'
+
+export default async function PostsPage() {
+ const queryClient = new QueryClient()
+
+ await queryClient.prefetchQuery({
+ queryKey: ['posts'],
+ queryFn: getPosts,
+ })
+
+ return (
+
+
+
+
+ )
+}
+
+// app/posts/comments-server.tsx
+import {
+ dehydrate,
+ HydrationBoundary,
+ QueryClient,
+} from '@tanstack/react-query'
+import Comments from './comments'
+
+export default async function CommentsServerComponent() {
+ const queryClient = new QueryClient()
+
+ await queryClient.prefetchQuery({
+ queryKey: ['posts-comments'],
+ queryFn: getComments,
+ })
+
+ return (
+
+
+
+ )
+}
+```
+
+可以多次使用 `` 并创建多个 `queryClient` 进行预取。注意由于在渲染 `CommentsServerComponent` 前等待 `getPosts`,会导致服务端瀑布流:
+
+```
+1. |> getPosts()
+2. |> getComments()
+```
+
+在 Next.js 中,除了在 `page.tsx` 预取数据,还可以在 `layout.tsx` 和[并行路由](https://nextjs.org/docs/app/building-your-application/routing/parallel-routes)中进行,Next.js 会自动并行获取这些路由数据。
+
+### 替代方案:使用单一 queryClient
+
+虽然推荐为每个服务器组件创建新的 `queryClient`,但也可以选择复用单个实例:
+
+```tsx
+// app/getQueryClient.tsx
+import { QueryClient } from '@tanstack/react-query'
+import { cache } from 'react'
+
+// cache() 按请求作用域,避免请求间数据泄漏
+const getQueryClient = cache(() => new QueryClient())
+export default getQueryClient
+```
+
+这样可以在任何服务器组件调用的地方获取该客户端,但每次 `dehydrate()` 都会序列化整个 `queryClient`,包括已序列化的无关查询。如果框架不会自动去重请求,这种方式可能更合适。
+
+未来可能引入 `dehydrateNew()` 函数仅序列化新增查询,欢迎参与贡献。
+
+### 数据所有权与重新验证
+
+在服务器组件中使用时需注意数据所有权问题。例如:
+
+```tsx
+// app/posts/page.tsx
+export default async function PostsPage() {
+ const queryClient = new QueryClient()
+ const posts = await queryClient.fetchQuery({
+ queryKey: ['posts'],
+ queryFn: getPosts,
+ })
+
+ return (
+
+ 文章数: {posts.length}
+
+
+ )
+}
+```
+
+当客户端重新验证数据时,服务组件中的 `文章数` 不会更新。如果设置 `staleTime: Infinity` 可以避免此问题,但这样就失去了使用 React Query 的意义。
+
+适合使用 React Query 与服务器组件的场景:
+
+- 已有 React Query 应用需要迁移到服务器组件
+- 需要结合服务器组件优势的特定用例
+- 框架提供的数据获取工具无法满足需求
+
+**新建服务器组件应用时,建议先使用框架提供的数据获取工具,确有需要再引入 React Query。**
+
+## 服务器组件的流式渲染
+
+Next.js 应用路由会自动流式传输已准备好的内容。使用上述预取模式时,React Query 完全兼容这种流式渲染。从 v5.40.0 开始,甚至可以脱水待处理查询,实现数据流式传输。
+
+需要调整 `queryClient` 配置以包含待处理查询:
+
+```tsx
+// app/get-query-client.ts
+import { QueryClient, defaultShouldDehydrateQuery } from '@tanstack/react-query'
+
+function makeQueryClient() {
+ return new QueryClient({
+ defaultOptions: {
+ dehydrate: {
+ shouldDehydrateQuery: (query) =>
+ defaultShouldDehydrateQuery(query) ||
+ query.state.status === 'pending',
+ },
+ },
+ })
+}
+```
+
+然后在页面组件中无需等待预取:
+
+```tsx
+// app/posts/page.tsx
+export default function PostsPage() {
+ const queryClient = getQueryClient()
+ queryClient.prefetchQuery({
+ queryKey: ['posts'],
+ queryFn: getPosts,
+ })
+
+ return (
+
+
+
+ )
+}
+```
+
+客户端组件可以使用 `useSuspenseQuery` 获取这些数据:
+
+```tsx
+// app/posts/posts.tsx
+'use client'
+
+export default function Posts() {
+ const { data } = useSuspenseQuery({ queryKey: ['posts'], queryFn: getPosts })
+ // ...
+}
+```
+
+如需处理非 JSON 数据类型,可以配置序列化/反序列化选项:
+
+```tsx
+// 配置序列化选项
+dehydrate: {
+ serializeData: serialize,
+},
+hydrate: {
+ deserializeData: deserialize,
+}
+```
+
+## Next.js 实验性无预取流式渲染
+
+虽然推荐上述预取方案,但也可以通过实验性包 `@tanstack/react-query-next-experimental` 实现无预取的流式 SSR。使用 `ReactQueryStreamedHydration` 包裹应用:
+
+```tsx
+// app/providers.tsx
+'use client'
+
+import { ReactQueryStreamedHydration } from '@tanstack/react-query-next-experimental'
+
+export function Providers({ children }) {
+ const queryClient = getQueryClient()
+ return (
+
+ {children}
+
+ )
+}
+```
+
+这种方式简化了代码但会导致页面导航时的请求瀑布流。适合更注重开发体验而非性能的场景。
+
+## 结语
+
+服务器组件和流式渲染仍是较新的概念,我们仍在探索如何优化 React Query 的集成。欢迎提供建议和反馈!同样,这份指南也在不断完善中,如果您发现遗漏或有改进建议,欢迎通过 GitHub 提交修改。
diff --git a/docs/zh-hans/framework/react/guides/background-fetching-indicators.md b/docs/zh-hans/framework/react/guides/background-fetching-indicators.md
new file mode 100644
index 00000000000..c36c11a7412
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/background-fetching-indicators.md
@@ -0,0 +1,64 @@
+---
+source-updated-at: '2024-01-25T20:57:22.000Z'
+translation-updated-at: '2025-05-06T04:14:14.853Z'
+id: background-fetching-indicators
+title: 后台获取指示器
+---
+
+# 后台获取指示器
+
+查询的 `status === 'pending'` 状态足以显示查询的初始硬加载状态,但有时您可能希望额外显示一个指示器,表明查询正在后台重新获取。为此,查询还提供了一个 `isFetching` 布尔值,您可以用它来显示查询正处于获取状态,而无论 `status` 变量的状态如何:
+
+[//]: # 'Example'
+
+```tsx
+function Todos() {
+ const {
+ status,
+ data: todos,
+ error,
+ isFetching,
+ } = useQuery({
+ queryKey: ['todos'],
+ queryFn: fetchTodos,
+ })
+
+ return status === 'pending' ? (
+ Loading...
+ ) : status === 'error' ? (
+ Error: {error.message}
+ ) : (
+ <>
+ {isFetching ? Refreshing...
: null}
+
+
+ {todos.map((todo) => (
+
+ ))}
+
+ >
+ )
+}
+```
+
+[//]: # 'Example'
+
+## 显示全局后台获取加载状态
+
+除了单个查询的加载状态外,如果您希望在**任何**查询获取时(包括在后台)显示全局加载指示器,可以使用 `useIsFetching` 钩子:
+
+[//]: # 'Example2'
+
+```tsx
+import { useIsFetching } from '@tanstack/react-query'
+
+function GlobalLoadingIndicator() {
+ const isFetching = useIsFetching()
+
+ return isFetching ? (
+ Queries are fetching in the background...
+ ) : null
+}
+```
+
+[//]: # 'Example2'
diff --git a/docs/zh-hans/framework/react/guides/caching.md b/docs/zh-hans/framework/react/guides/caching.md
new file mode 100644
index 00000000000..f8296c1ced6
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/caching.md
@@ -0,0 +1,45 @@
+---
+source-updated-at: '2025-03-18T08:45:11.000Z'
+translation-updated-at: '2025-05-06T04:14:25.884Z'
+id: caching
+title: 缓存
+---
+
+> 在阅读本指南前,请务必先通读[重要默认配置](./important-defaults.md)
+
+## 基础示例
+
+这个缓存示例演示了以下场景及其生命周期:
+
+- 包含缓存数据与不包含缓存数据的查询实例 (Query Instances)
+- 后台重新获取 (Background Refetching)
+- 非活跃查询 (Inactive Queries)
+- 垃圾回收 (Garbage Collection)
+
+假设我们使用默认的 `gcTime`(**5分钟**)和默认的 `staleTime`(`0`)。
+
+1. 首次挂载 `useQuery({ queryKey: ['todos'], queryFn: fetchTodos })`:
+
+ - 由于此前没有使用 `['todos']` 查询键 (query key) 发起过其他查询,该查询会显示硬加载状态 (hard loading state) 并通过网络请求获取数据。
+ - 当网络请求完成时,返回的数据会缓存在 `['todos']` 键下。
+ - 在配置的 `staleTime`(默认为 `0`,即立即)后,数据会被标记为过时 (stale)。
+
+2. 在其他位置挂载第二个 `useQuery({ queryKey: ['todos'], queryFn: fetchTodos })` 实例:
+
+ - 由于缓存中已存在第一个查询的 `['todos']` 键数据,会立即从缓存返回该数据。
+ - 新实例会使用其查询函数触发新的网络请求。
+ - 注意:无论两个 `fetchTodos` 查询函数是否相同,只要查询键相同,两个查询的 [`status`](../reference/useQuery.md)(包括 `isFetching`、`isPending` 等相关值)都会同步更新。
+ - 当请求成功完成时,`['todos']` 键下的缓存数据会更新,两个实例都会接收到新数据。
+
+3. 当两个 `useQuery({ queryKey: ['todos'], queryFn: fetchTodos })` 实例都卸载且不再使用时:
+
+ - 由于该查询没有活跃实例,会使用 `gcTime`(默认为 **5分钟**)设置垃圾回收超时,之后该查询将被删除并回收。
+
+4. 在缓存超时完成前,再次挂载 `useQuery({ queryKey: ['todos'], queryFn: fetchTodos })`:
+
+ - 查询会立即返回可用的缓存数据,同时在后台执行 `fetchTodos` 函数。成功完成后会用新数据更新缓存。
+
+5. 最后一个 `useQuery({ queryKey: ['todos'], queryFn: fetchTodos })` 实例卸载。
+
+6. 在 **5分钟** 内没有出现新的 `useQuery({ queryKey: ['todos'], queryFn: fetchTodos })` 实例:
+ - `['todos']` 键下的缓存数据会被删除并进行垃圾回收。
diff --git a/docs/zh-hans/framework/react/guides/default-query-function.md b/docs/zh-hans/framework/react/guides/default-query-function.md
new file mode 100644
index 00000000000..28f408def8d
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/default-query-function.md
@@ -0,0 +1,58 @@
+---
+source-updated-at: '2024-01-25T20:57:22.000Z'
+translation-updated-at: '2025-05-06T04:13:52.792Z'
+id: default-query-function
+title: 默认查询函数
+---
+
+如果你出于任何原因,希望在整个应用中共享同一个查询函数,仅通过查询键 (query key) 来标识应该获取的数据,可以通过为 TanStack Query 提供一个 **默认查询函数 (default query function)** 来实现:
+
+[//]: # '示例'
+
+```tsx
+// 定义一个默认查询函数,它将接收查询键
+const defaultQueryFn = async ({ queryKey }) => {
+ const { data } = await axios.get(
+ `https://jsonplaceholder.typicode.com${queryKey[0]}`,
+ )
+ return data
+}
+
+// 通过 defaultOptions 将默认查询函数提供给整个应用
+const queryClient = new QueryClient({
+ defaultOptions: {
+ queries: {
+ queryFn: defaultQueryFn,
+ },
+ },
+})
+
+function App() {
+ return (
+
+
+
+ )
+}
+
+// 现在你只需要传递一个键即可!
+function Posts() {
+ const { status, data, error, isFetching } = useQuery({ queryKey: ['/posts'] })
+
+ // ...
+}
+
+// 你甚至可以省略 queryFn,直接传入选项
+function Post({ postId }) {
+ const { status, data, error, isFetching } = useQuery({
+ queryKey: [`/posts/${postId}`],
+ enabled: !!postId,
+ })
+
+ // ...
+}
+```
+
+[//]: # '示例'
+
+如果你想覆盖默认的 queryFn,只需像平常那样提供自己的查询函数即可。
diff --git a/docs/zh-hans/framework/react/guides/dependent-queries.md b/docs/zh-hans/framework/react/guides/dependent-queries.md
new file mode 100644
index 00000000000..4a0930bd43d
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/dependent-queries.md
@@ -0,0 +1,97 @@
+---
+source-updated-at: '2025-03-18T08:45:11.000Z'
+translation-updated-at: '2025-05-06T04:14:02.726Z'
+id: dependent-queries
+title: 依赖查询
+---
+
+## useQuery 依赖查询
+
+依赖(或串行)查询需要等待前一个查询完成才能执行。实现这一功能非常简单,只需使用 `enabled` 选项来指定查询何时可以运行:
+
+[//]: # '示例'
+
+```tsx
+// 获取用户信息
+const { data: user } = useQuery({
+ queryKey: ['user', email],
+ queryFn: getUserByEmail,
+})
+
+const userId = user?.id
+
+// 然后获取该用户的项目列表
+const {
+ status,
+ fetchStatus,
+ data: projects,
+} = useQuery({
+ queryKey: ['projects', userId],
+ queryFn: getProjectsByUser,
+ // 只有当 userId 存在时才会执行查询
+ enabled: !!userId,
+})
+```
+
+[//]: # '示例'
+
+`projects` 查询的初始状态为:
+
+```tsx
+status: 'pending'
+isPending: true
+fetchStatus: 'idle'
+```
+
+当 `user` 数据就绪后,`projects` 查询会被 `enabled` 并转为:
+
+```tsx
+status: 'pending'
+isPending: true
+fetchStatus: 'fetching'
+```
+
+当项目数据获取完成后,状态将变为:
+
+```tsx
+status: 'success'
+isPending: false
+fetchStatus: 'idle'
+```
+
+## useQueries 依赖查询
+
+动态并行查询 - `useQueries` 也可以依赖前一个查询,实现方式如下:
+
+[//]: # '示例2'
+
+```tsx
+// 获取用户ID列表
+const { data: userIds } = useQuery({
+ queryKey: ['users'],
+ queryFn: getUsersData,
+ select: (users) => users.map((user) => user.id),
+})
+
+// 然后获取各用户的消息
+const usersMessages = useQueries({
+ queries: userIds
+ ? userIds.map((id) => {
+ return {
+ queryKey: ['messages', id],
+ queryFn: () => getMessagesByUsers(id),
+ }
+ })
+ : [], // 如果users未定义,则返回空数组
+})
+```
+
+[//]: # '示例2'
+
+**注意** `useQueries` 返回的是**查询结果数组**
+
+## 性能说明
+
+依赖查询本质上构成了[请求瀑布流](./request-waterfalls.md),会影响性能。假设两个查询耗时相同,串行执行总是比并行执行多花一倍时间,这在客户端高延迟环境下尤其不利。如果可能,最好重构后端API使两个查询能并行获取,尽管这并非总是可行。
+
+在上面的例子中,与其先获取`getUserByEmail`才能执行`getProjectsByUser`,不如新增一个`getProjectsByUserEmail`查询来消除瀑布流。
diff --git a/docs/zh-hans/framework/react/guides/disabling-queries.md b/docs/zh-hans/framework/react/guides/disabling-queries.md
new file mode 100644
index 00000000000..ccd341f9985
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/disabling-queries.md
@@ -0,0 +1,130 @@
+---
+source-updated-at: '2025-01-10T12:49:47.000Z'
+translation-updated-at: '2025-05-06T04:14:23.656Z'
+id: disabling-queries
+title: 禁用/暂停查询
+---
+
+若需阻止查询自动执行,可通过设置 `enabled = false` 选项实现。该选项也支持传入返回布尔值的回调函数。
+
+当 `enabled` 为 `false` 时:
+
+- 若查询存在缓存数据,则初始化状态为 `status === 'success'` 或 `isSuccess`
+- 若查询无缓存数据,则初始化状态为 `status === 'pending'` 且 `fetchStatus === 'idle'`
+- 查询不会在挂载时自动触发
+- 查询不会在后台自动重新获取
+- 查询会忽略 query client 的 `invalidateQueries` 和 `refetchQueries` 调用(这些调用通常会导致查询重新获取)
+- 通过 `useQuery` 返回的 `refetch` 可手动触发查询,但无法与 `skipToken` 配合使用
+
+> TypeScript 用户可选用 [skipToken](#typesafe-disabling-of-queries-using-skiptoken) 作为 `enabled = false` 的替代方案
+
+[//]: # '示例'
+
+```tsx
+function Todos() {
+ const { isLoading, isError, data, error, refetch, isFetching } = useQuery({
+ queryKey: ['todos'],
+ queryFn: fetchTodoList,
+ enabled: false,
+ })
+
+ return (
+
+
refetch()}>Fetch Todos
+
+ {data ? (
+ <>
+
+ {data.map((todo) => (
+ {todo.title}
+ ))}
+
+ >
+ ) : isError ? (
+
Error: {error.message}
+ ) : isLoading ? (
+
Loading...
+ ) : (
+
Not ready ...
+ )}
+
+
{isFetching ? 'Fetching...' : null}
+
+ )
+}
+```
+
+[//]: # '示例'
+
+永久禁用查询会使你失去 TanStack Query 的许多优秀特性(如后台重新获取),这也不符合惯用模式。这会让你从声明式模式(定义查询执行依赖)退化为命令式模式(点击按钮时才获取)。此外也无法通过 `refetch` 传递参数。多数情况下,你需要的只是一个延迟初始获取的惰性查询:
+
+## 惰性查询
+
+`enabled` 选项不仅能永久禁用查询,还能实现动态启用/禁用。典型场景是筛选表单——仅当用户输入筛选值后才发起首次请求:
+
+[//]: # '示例2'
+
+```tsx
+function Todos() {
+ const [filter, setFilter] = React.useState('')
+
+ const { data } = useQuery({
+ queryKey: ['todos', filter],
+ queryFn: () => fetchTodos(filter),
+ // ⬇️ 当筛选值为空时禁用查询
+ enabled: !!filter,
+ })
+
+ return (
+
+ // 🚀 应用筛选条件将启用并执行查询
+
+ {data && }
+
+ )
+}
+```
+
+[//]: # '示例2'
+
+### isLoading (原 `isInitialLoading`)
+
+惰性查询会始终处于 `status: 'pending'` 状态,因为 `pending` 表示尚无数据。虽然技术上是正确的,但由于当前并未获取数据(查询未被 _启用_),这个标志位通常不能用于显示加载指示器。
+
+若使用禁用或惰性查询,可改用 `isLoading` 标志位。这是一个衍生标志,由以下公式计算:
+
+`isPending && isFetching`
+
+因此仅当查询首次获取数据时才会为 `true`
+
+## 使用 `skipToken` 实现类型安全的查询禁用
+
+TypeScript 用户可使用 `skipToken` 禁用查询。适用于需要基于条件禁用查询,同时保持类型安全的场景。
+
+> 重要提示:`useQuery` 返回的 `refetch` 无法与 `skipToken` 配合使用。除此之外,`skipToken` 与 `enabled: false` 行为一致
+
+[//]: # '示例3'
+
+```tsx
+import { skipToken, useQuery } from '@tanstack/react-query'
+
+function Todos() {
+ const [filter, setFilter] = React.useState()
+
+ const { data } = useQuery({
+ queryKey: ['todos', filter],
+ // ⬇️ 当 filter 为 undefined 或空时禁用查询
+ queryFn: filter ? () => fetchTodos(filter) : skipToken,
+ })
+
+ return (
+
+ // 🚀 应用筛选条件将启用并执行查询
+
+ {data && }
+
+ )
+}
+```
+
+[//]: # '示例3'
diff --git a/docs/zh-hans/framework/react/guides/does-this-replace-client-state.md b/docs/zh-hans/framework/react/guides/does-this-replace-client-state.md
new file mode 100644
index 00000000000..bdfbef44134
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/does-this-replace-client-state.md
@@ -0,0 +1,58 @@
+---
+source-updated-at: '2024-01-25T20:57:22.000Z'
+translation-updated-at: '2025-05-06T04:14:00.417Z'
+id: does-this-replace-client-state
+title: '这会取代 [Redux, MobX 等] 吗?'
+---
+
+首先,我们需要明确几个关键点:
+
+- TanStack Query 是一个**服务端状态 (server-state)** 库,负责管理服务器与客户端之间的异步操作
+- Redux、MobX、Zustand 等属于**客户端状态 (client-state)** 库,它们*虽然可以用来存储异步数据,但与 TanStack Query 这类工具相比效率较低*
+
+基于以上认知,简短的答案是:TanStack Query **取代了那些用于管理客户端状态中缓存数据的样板代码和相关连接逻辑,仅需寥寥数行代码即可实现相同功能**。
+
+对于绝大多数应用而言,当把所有异步代码迁移到 TanStack Query 后,剩余的真正**需要全局访问的客户端状态**通常非常少。
+
+> 当然也存在特殊情况:某些应用可能确实拥有大量同步的纯客户端状态(例如可视化设计工具或音乐制作软件),这种情况下您可能仍需要客户端状态管理工具。此时需要注意——**TanStack Query 并不能替代本地/客户端状态管理**。不过您可以毫无障碍地将其与大多数客户端状态管理器配合使用。
+
+## 示例说明
+
+假设我们有以下通过全局状态库管理的"全局"状态:
+
+```tsx
+const globalState = {
+ projects,
+ teams,
+ tasks,
+ users,
+ themeMode,
+ sidebarStatus,
+}
+```
+
+当前全局状态管理器缓存了4类服务端状态:`projects`、`teams`、`tasks` 和 `users`。如果将这些服务端状态迁移到 TanStack Query,剩余的全局状态将简化为:
+
+```tsx
+const globalState = {
+ themeMode,
+ sidebarStatus,
+}
+```
+
+这意味着通过调用 `useQuery` 和 `useMutation` 等钩子,我们还能移除所有用于管理服务端状态的样板代码,例如:
+
+- 连接器 (Connectors)
+- 动作创建器 (Action Creators)
+- 中间件 (Middlewares)
+- 归约器 (Reducers)
+- 加载中/错误/结果状态 (Loading/Error/Result states)
+- 上下文 (Contexts)
+
+移除这些内容后,您可能会思考:**"是否还有必要为这点儿全局状态继续使用客户端状态管理器?"**
+
+**这完全取决于您!**
+
+但 TanStack Query 的定位非常明确——它能消除应用中所有异步连接的样板代码,仅需少量代码即可替代。
+
+还在等什么?赶快试试看吧!
diff --git a/docs/zh-hans/framework/react/guides/filters.md b/docs/zh-hans/framework/react/guides/filters.md
new file mode 100644
index 00000000000..c191b471710
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/filters.md
@@ -0,0 +1,92 @@
+---
+source-updated-at: '2025-01-26T18:24:42.000Z'
+translation-updated-at: '2025-05-06T04:14:12.171Z'
+id: filters
+title: 过滤器
+---
+
+TanStack Query 中的部分方法接受 `QueryFilters` 或 `MutationFilters` 对象作为参数。
+
+## `查询过滤器 (Query Filters)`
+
+查询过滤器 (Query Filter) 是一个包含特定匹配条件的对象,用于筛选查询:
+
+```tsx
+// 取消所有查询
+await queryClient.cancelQueries()
+
+// 移除所有键名以 `posts` 开头的非活跃 (inactive) 查询
+queryClient.removeQueries({ queryKey: ['posts'], type: 'inactive' })
+
+// 重新获取所有活跃 (active) 查询
+await queryClient.refetchQueries({ type: 'active' })
+
+// 重新获取所有键名以 `posts` 开头的活跃 (active) 查询
+await queryClient.refetchQueries({ queryKey: ['posts'], type: 'active' })
+```
+
+查询过滤器对象支持以下属性:
+
+- `queryKey?: QueryKey`
+ - 设置此属性可定义需要匹配的查询键 (query key)。
+- `exact?: boolean`
+ - 若不需要通过查询键 (query key) 进行包容性搜索,可传递 `exact: true` 选项,仅返回与指定查询键完全匹配的查询。
+- `type?: 'active' | 'inactive' | 'all'`
+ - 默认值为 `all`
+ - 设置为 `active` 时匹配活跃 (active) 查询。
+ - 设置为 `inactive` 时匹配非活跃 (inactive) 查询。
+- `stale?: boolean`
+ - 设置为 `true` 时匹配过时 (stale) 查询。
+ - 设置为 `false` 时匹配新鲜 (fresh) 查询。
+- `fetchStatus?: FetchStatus`
+ - 设置为 `fetching` 时匹配当前正在获取 (fetching) 的查询。
+ - 设置为 `paused` 时匹配希望获取但被 `暂停 (paused)` 的查询。
+ - 设置为 `idle` 时匹配未在获取数据的查询。
+- `predicate?: (query: Query) => boolean`
+ - 此谓词函数将作为对所有匹配查询的最终筛选条件。如果未指定其他过滤器,该函数将针对缓存中的每个查询进行评估。
+
+## `变更过滤器 (Mutation Filters)`
+
+变更过滤器 (Mutation Filter) 是一个包含特定匹配条件的对象,用于筛选变更:
+
+```tsx
+// 获取所有正在获取的变更数量
+await queryClient.isMutating()
+
+// 通过变更键 (mutationKey) 筛选变更
+await queryClient.isMutating({ mutationKey: ['post'] })
+
+// 使用谓词函数筛选变更
+await queryClient.isMutating({
+ predicate: (mutation) => mutation.state.variables?.id === 1,
+})
+```
+
+变更过滤器对象支持以下属性:
+
+- `mutationKey?: MutationKey`
+ - 设置此属性可定义需要匹配的变更键 (mutation key)。
+- `exact?: boolean`
+ - 若不需要通过变更键 (mutation key) 进行包容性搜索,可传递 `exact: true` 选项,仅返回与指定变更键完全匹配的变更。
+- `status?: MutationStatus`
+ - 允许根据变更状态进行筛选。
+- `predicate?: (mutation: Mutation) => boolean`
+ - 此谓词函数将作为对所有匹配变更的最终筛选条件。如果未指定其他过滤器,该函数将针对缓存中的每个变更进行评估。
+
+## 工具函数 (Utils)
+
+### `matchQuery`
+
+```tsx
+const isMatching = matchQuery(filters, query)
+```
+
+返回一个布尔值,指示查询是否匹配提供的查询过滤器集合。
+
+### `matchMutation`
+
+```tsx
+const isMatching = matchMutation(filters, mutation)
+```
+
+返回一个布尔值,指示变更是否匹配提供的变更过滤器集合。
diff --git a/docs/zh-hans/framework/react/guides/important-defaults.md b/docs/zh-hans/framework/react/guides/important-defaults.md
new file mode 100644
index 00000000000..f31af8891e2
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/important-defaults.md
@@ -0,0 +1,44 @@
+---
+source-updated-at: '2025-03-18T08:45:11.000Z'
+translation-updated-at: '2025-05-06T04:12:55.170Z'
+id: important-defaults
+title: 重要默认设置
+---
+
+开箱即用,TanStack Query 采用了**激进但合理**的默认配置。**这些默认设置有时会让新用户措手不及,如果用户不了解它们,可能会增加学习或调试的难度。**在继续学习和使用 TanStack Query 时,请牢记以下要点:
+
+- 通过 `useQuery` 或 `useInfiniteQuery` 创建的查询实例默认**将缓存数据视为过时数据**。
+
+> 若要修改此行为,可通过全局配置或单查询配置使用 `staleTime` 选项。设置较长的 `staleTime` 意味着查询不会频繁重新获取数据。
+
+- 当满足以下条件时,过时查询会在后台自动重新获取数据:
+ - 新的查询实例挂载
+ - 窗口重新获得焦点
+ - 网络重新连接
+ - 查询配置了可选的 refetch 间隔时间
+
+> 可通过 `refetchOnMount`、`refetchOnWindowFocus`、`refetchOnReconnect` 和 `refetchInterval` 等选项调整此功能。
+
+- 当 `useQuery`、`useInfiniteQuery` 或查询观察者不再有活跃实例时,对应的查询结果会被标记为"非活跃"状态,并保留在缓存中供后续使用。
+- 默认情况下,"非活跃"查询会在 **5 分钟后**被垃圾回收。
+
+ > 可通过修改默认的 `gcTime`(当前为 `1000 * 60 * 5` 毫秒)来调整此设置。
+
+- 失败的查询会**静默重试 3 次**,采用指数退避延迟策略,之后才会捕获错误并显示到用户界面。
+
+ > 可通过修改默认的 `retry`(重试次数)和 `retryDelay`(退避延迟函数)选项来调整此行为。
+
+- 默认情况下,查询结果会进行**结构共享比较以检测数据是否实际变化**。如果数据未变化,则**保持数据引用不变**,从而更好地配合 useMemo 和 useCallback 实现值稳定性。如果这个概念听起来陌生,无需担心!99.9% 的情况下您不需要禁用此功能,它能零成本提升应用性能。
+
+ > 结构共享仅适用于 JSON 兼容值,其他值类型始终会被视为已变化。例如,若因响应数据过大导致性能问题,可通过 `config.structuralSharing` 标志禁用此功能。若查询响应包含非 JSON 兼容值但仍需检测数据变化,可提供自定义函数作为 `config.structuralSharing`,根据新旧响应计算值并按需保持引用。
+
+[//]: # 'Materials'
+
+## 扩展阅读
+
+查看以下社区资源文章,深入了解默认配置的原理:
+
+- [React Query 实战指南](../community/tkdodos-blog.md#1-practical-react-query)
+- [作为状态管理器的 React Query](../community/tkdodos-blog.md#10-react-query-as-a-state-manager)
+
+[//]: # 'Materials'
diff --git a/docs/zh-hans/framework/react/guides/infinite-queries.md b/docs/zh-hans/framework/react/guides/infinite-queries.md
new file mode 100644
index 00000000000..287e3a4c7d2
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/infinite-queries.md
@@ -0,0 +1,263 @@
+---
+source-updated-at: '2024-11-18T17:22:25.000Z'
+translation-updated-at: '2025-05-06T04:13:56.367Z'
+id: infinite-queries
+title: 无限查询
+---
+
+## 无限查询 (Infinite Queries)
+
+能够以增量方式"加载更多"数据到现有数据集或实现"无限滚动"的列表渲染,是一种非常常见的 UI 模式。TanStack Query 为此提供了一个名为 `useInfiniteQuery` 的特殊版本 `useQuery` 来查询这类列表。
+
+使用 `useInfiniteQuery` 时,您会注意到以下几点不同:
+
+- `data` 现在是一个包含无限查询数据的对象:
+ - `data.pages` 数组包含已获取的页面
+ - `data.pageParams` 数组包含用于获取页面的参数
+- 现在可以使用 `fetchNextPage` 和 `fetchPreviousPage` 函数(`fetchNextPage` 是必需的)
+- 新增了 `initialPageParam` 选项(且必需)用于指定初始页面参数
+- 新增了 `getNextPageParam` 和 `getPreviousPageParam` 选项,用于确定是否有更多数据要加载以及获取这些数据所需的信息。这些信息会作为查询函数的附加参数提供
+- 新增了 `hasNextPage` 布尔值,当 `getNextPageParam` 返回值不是 `null` 或 `undefined` 时为 `true`
+- 新增了 `hasPreviousPage` 布尔值,当 `getPreviousPageParam` 返回值不是 `null` 或 `undefined` 时为 `true`
+- 新增了 `isFetchingNextPage` 和 `isFetchingPreviousPage` 布尔值,用于区分后台刷新状态和加载更多状态
+
+> 注意:选项 `initialData` 或 `placeholderData` 需要遵循与包含 `data.pages` 和 `data.pageParams` 属性的对象相同的结构。
+
+## 示例
+
+假设我们有一个 API,它基于 `cursor` 索引每次返回 3 个 `projects` 页面,同时返回可用于获取下一组项目的游标:
+
+```tsx
+fetch('/api/projects?cursor=0')
+// { data: [...], nextCursor: 3}
+fetch('/api/projects?cursor=3')
+// { data: [...], nextCursor: 6}
+fetch('/api/projects?cursor=6')
+// { data: [...], nextCursor: 9}
+fetch('/api/projects?cursor=9')
+// { data: [...] }
+```
+
+利用这些信息,我们可以通过以下方式创建一个"加载更多"的 UI:
+
+- 默认等待 `useInfiniteQuery` 请求第一组数据
+- 在 `getNextPageParam` 中返回下一个查询的信息
+- 调用 `fetchNextPage` 函数
+
+[//]: # '示例'
+
+```tsx
+import { useInfiniteQuery } from '@tanstack/react-query'
+
+function Projects() {
+ const fetchProjects = async ({ pageParam }) => {
+ const res = await fetch('/api/projects?cursor=' + pageParam)
+ return res.json()
+ }
+
+ const {
+ data,
+ error,
+ fetchNextPage,
+ hasNextPage,
+ isFetching,
+ isFetchingNextPage,
+ status,
+ } = useInfiniteQuery({
+ queryKey: ['projects'],
+ queryFn: fetchProjects,
+ initialPageParam: 0,
+ getNextPageParam: (lastPage, pages) => lastPage.nextCursor,
+ })
+
+ return status === 'pending' ? (
+ 加载中...
+ ) : status === 'error' ? (
+ 错误: {error.message}
+ ) : (
+ <>
+ {data.pages.map((group, i) => (
+
+ {group.data.map((project) => (
+ {project.name}
+ ))}
+
+ ))}
+
+ fetchNextPage()}
+ disabled={!hasNextPage || isFetchingNextPage}
+ >
+ {isFetchingNextPage
+ ? '正在加载更多...'
+ : hasNextPage
+ ? '加载更多'
+ : '已加载全部'}
+
+
+ {isFetching && !isFetchingNextPage ? '获取中...' : null}
+ >
+ )
+}
+```
+
+[//]: # '示例'
+
+必须理解的是,在正在进行获取时调用 `fetchNextPage` 会有覆盖后台数据刷新的风险。当同时渲染列表和触发 `fetchNextPage` 时,这种情况变得尤为关键。
+
+请记住,一个 InfiniteQuery 只能有一个正在进行的获取操作。所有页面共享一个缓存条目,尝试同时进行两次获取可能会导致数据覆盖。
+
+如果您希望启用同时获取,可以在 `fetchNextPage` 中使用 `{ cancelRefetch: false }` 选项(默认为 true)。
+
+为了确保无冲突的顺畅查询过程,强烈建议验证查询是否不处于 `isFetching` 状态,特别是当用户不会直接控制该调用时。
+
+[//]: # '示例1'
+
+```jsx
+ !isFetchingNextPage && fetchNextPage()} />
+```
+
+[//]: # '示例1'
+
+## 当无限查询需要重新获取时会发生什么?
+
+当无限查询变为 `stale` 并需要重新获取时,每组数据会从第一组开始`顺序`获取。这确保了即使底层数据发生变更,我们也不会使用过期的游标,从而避免获取重复记录或跳过记录。如果无限查询的结果从 queryCache 中移除,分页将从初始状态重新开始,仅请求初始组。
+
+## 如何实现双向无限列表?
+
+双向列表可以通过使用 `getPreviousPageParam`、`fetchPreviousPage`、`hasPreviousPage` 和 `isFetchingPreviousPage` 属性和函数来实现。
+
+[//]: # '示例3'
+
+```tsx
+useInfiniteQuery({
+ queryKey: ['projects'],
+ queryFn: fetchProjects,
+ initialPageParam: 0,
+ getNextPageParam: (lastPage, pages) => lastPage.nextCursor,
+ getPreviousPageParam: (firstPage, pages) => firstPage.prevCursor,
+})
+```
+
+[//]: # '示例3'
+
+## 如何以倒序显示页面?
+
+有时您可能希望以倒序显示页面。这种情况下,可以使用 `select` 选项:
+
+[//]: # '示例4'
+
+```tsx
+useInfiniteQuery({
+ queryKey: ['projects'],
+ queryFn: fetchProjects,
+ select: (data) => ({
+ pages: [...data.pages].reverse(),
+ pageParams: [...data.pageParams].reverse(),
+ }),
+})
+```
+
+[//]: # '示例4'
+
+## 如何手动更新无限查询?
+
+### 手动移除第一页:
+
+[//]: # '示例5'
+
+```tsx
+queryClient.setQueryData(['projects'], (data) => ({
+ pages: data.pages.slice(1),
+ pageParams: data.pageParams.slice(1),
+}))
+```
+
+[//]: # '示例5'
+
+### 手动从单个页面中移除某个值:
+
+[//]: # '示例6'
+
+```tsx
+const newPagesArray =
+ oldPagesArray?.pages.map((page) =>
+ page.filter((val) => val.id !== updatedId),
+ ) ?? []
+
+queryClient.setQueryData(['projects'], (data) => ({
+ pages: newPagesArray,
+ pageParams: data.pageParams,
+}))
+```
+
+[//]: # '示例6'
+
+### 仅保留第一页:
+
+[//]: # '示例7'
+
+```tsx
+queryClient.setQueryData(['projects'], (data) => ({
+ pages: data.pages.slice(0, 1),
+ pageParams: data.pageParams.slice(0, 1),
+}))
+```
+
+[//]: # '示例7'
+
+确保始终保持 pages 和 pageParams 的相同数据结构!
+
+## 如何限制页面数量?
+
+在某些用例中,您可能希望限制查询数据中存储的页面数量以提高性能和用户体验:
+
+- 当用户可以加载大量页面时(内存使用)
+- 当需要重新获取包含数十个页面的无限查询时(网络使用:所有页面都会按顺序获取)
+
+解决方案是使用"有限无限查询"。这可以通过将 `maxPages` 选项与 `getNextPageParam` 和 `getPreviousPageParam` 结合使用来实现,以便在需要时双向获取页面。
+
+在以下示例中,查询数据 pages 数组中仅保留 3 页。如果需要重新获取,只会按顺序重新获取 3 页。
+
+[//]: # '示例8'
+
+```tsx
+useInfiniteQuery({
+ queryKey: ['projects'],
+ queryFn: fetchProjects,
+ initialPageParam: 0,
+ getNextPageParam: (lastPage, pages) => lastPage.nextCursor,
+ getPreviousPageParam: (firstPage, pages) => firstPage.prevCursor,
+ maxPages: 3,
+})
+```
+
+[//]: # '示例8'
+
+## 如果我的 API 不返回游标怎么办?
+
+如果您的 API 不返回游标,可以将 `pageParam` 用作游标。因为 `getNextPageParam` 和 `getPreviousPageParam` 也会获取当前页面的 `pageParam`,所以可以用它来计算下一个/上一个页面参数。
+
+[//]: # '示例9'
+
+```tsx
+return useInfiniteQuery({
+ queryKey: ['projects'],
+ queryFn: fetchProjects,
+ initialPageParam: 0,
+ getNextPageParam: (lastPage, allPages, lastPageParam) => {
+ if (lastPage.length === 0) {
+ return undefined
+ }
+ return lastPageParam + 1
+ },
+ getPreviousPageParam: (firstPage, allPages, firstPageParam) => {
+ if (firstPageParam <= 1) {
+ return undefined
+ }
+ return firstPageParam - 1
+ },
+})
+```
+
+[//]: # '示例9'
diff --git a/docs/zh-hans/framework/react/guides/initial-query-data.md b/docs/zh-hans/framework/react/guides/initial-query-data.md
new file mode 100644
index 00000000000..49e3408fae5
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/initial-query-data.md
@@ -0,0 +1,176 @@
+---
+source-updated-at: '2025-03-18T08:45:11.000Z'
+translation-updated-at: '2025-05-06T04:13:31.868Z'
+id: initial-query-data
+title: 初始查询数据
+---
+
+在需要之前,有多种方式可以为查询缓存提供初始数据:
+
+- 声明式:
+ - 通过 `initialData` 为查询预填充空缓存
+- 命令式:
+ - [使用 `queryClient.prefetchQuery` 预取数据](./prefetching.md)
+ - [使用 `queryClient.setQueryData` 手动将数据存入缓存](./prefetching.md)
+
+## 使用 `initialData` 预填充查询
+
+有时应用中已存在查询所需的初始数据,可直接提供给查询。此时可通过 `config.initialData` 选项设置查询初始数据,并跳过初始加载状态!
+
+> 重要提示:`initialData` 会持久化到缓存,因此不建议向该选项提供占位、部分或不完整数据,应改用 `placeholderData`
+
+[//]: # '示例'
+
+```tsx
+const result = useQuery({
+ queryKey: ['todos'],
+ queryFn: () => fetch('/todos'),
+ initialData: initialTodos,
+})
+```
+
+[//]: # '示例'
+
+### `staleTime` 与 `initialDataUpdatedAt`
+
+默认情况下,`initialData` 被视为全新数据(如同刚获取的数据)。这会影响 `staleTime` 选项的解读方式:
+
+- 若为查询观察者配置 `initialData` 且未设置 `staleTime`(默认 `staleTime: 0`),挂载时会立即重新获取数据:
+
+ [//]: # '示例2'
+
+ ```tsx
+ // 立即显示 initialTodos,但挂载后会立即重新获取 todos
+ const result = useQuery({
+ queryKey: ['todos'],
+ queryFn: () => fetch('/todos'),
+ initialData: initialTodos,
+ })
+ ```
+
+ [//]: # '示例2'
+
+- 若配置 `initialData` 并设置 `staleTime` 为 `1000` 毫秒,数据在该时间段内将被视为新鲜数据(如同刚从查询函数获取):
+
+ [//]: # '示例3'
+
+ ```tsx
+ // 立即显示 initialTodos,但在 1000 毫秒后遇到交互事件前不会重新获取
+ const result = useQuery({
+ queryKey: ['todos'],
+ queryFn: () => fetch('/todos'),
+ initialData: initialTodos,
+ staleTime: 1000,
+ })
+ ```
+
+ [//]: # '示例3'
+
+- 如果 `initialData` 并非完全新鲜?此时最准确的配置是使用 `initialDataUpdatedAt` 选项。该选项允许传入 JS 时间戳(毫秒)表示初始数据的最后更新时间(如 `Date.now()` 提供的值)。注意:若使用 Unix 时间戳需乘以 `1000` 转换为 JS 时间戳。
+
+ [//]: # '示例4'
+
+ ```tsx
+ // 立即显示 initialTodos,但仅在 initialData 早于 staleTime 时挂载重新获取
+ const result = useQuery({
+ queryKey: ['todos'],
+ queryFn: () => fetch('/todos'),
+ initialData: initialTodos,
+ staleTime: 60 * 1000, // 1 分钟
+ initialDataUpdatedAt: initialTodosUpdatedTimestamp, // 例如 1608412420052
+ })
+ ```
+
+ [//]: # '示例4'
+
+ 该选项使得 `staleTime` 能按其原始目的(确定数据需保持新鲜的时间)运作,同时允许在 `initialData` 早于 `staleTime` 时挂载重新获取。上例中数据需在 1 分钟内保持新鲜,通过提示初始数据的更新时间,查询能自行决定是否需要重新获取。
+
+ > 若希望将数据视为**预取数据**,建议使用 `prefetchQuery` 或 `fetchQuery` API 预先填充缓存,从而独立配置 `staleTime` 与初始数据
+
+### 初始数据函数
+
+若获取查询初始数据的操作开销较大或不想在每次渲染时执行,可传递函数作为 `initialData` 值。该函数仅在查询初始化时执行一次,节省内存和 CPU 资源:
+
+[//]: # '示例5'
+
+```tsx
+const result = useQuery({
+ queryKey: ['todos'],
+ queryFn: () => fetch('/todos'),
+ initialData: () => getExpensiveTodos(),
+})
+```
+
+[//]: # '示例5'
+
+### 从缓存获取初始数据
+
+某些情况下,可以从其他查询的缓存结果中提供初始数据。典型场景是从待办列表查询缓存中搜索单个待办项,并将其作为单个待办查询的初始数据:
+
+[//]: # '示例6'
+
+```tsx
+const result = useQuery({
+ queryKey: ['todo', todoId],
+ queryFn: () => fetch('/todos'),
+ initialData: () => {
+ // 使用 'todos' 查询中的待办项作为本查询的初始数据
+ return queryClient.getQueryData(['todos'])?.find((d) => d.id === todoId)
+ },
+})
+```
+
+[//]: # '示例6'
+
+### 使用 `initialDataUpdatedAt` 从缓存获取初始数据
+
+从缓存获取初始数据意味着源查询的数据可能已过时。建议将源查询的 `dataUpdatedAt` 传递给 `initialDataUpdatedAt`,而非使用人为的 `staleTime` 防止立即重新获取。这为查询实例提供了判断是否需要重新获取的全部信息:
+
+[//]: # '示例7'
+
+```tsx
+const result = useQuery({
+ queryKey: ['todos', todoId],
+ queryFn: () => fetch(`/todos/${todoId}`),
+ initialData: () =>
+ queryClient.getQueryData(['todos'])?.find((d) => d.id === todoId),
+ initialDataUpdatedAt: () =>
+ queryClient.getQueryState(['todos'])?.dataUpdatedAt,
+})
+```
+
+[//]: # '示例7'
+
+### 有条件地从缓存获取初始数据
+
+若用于查找初始数据的源查询已过时,可能希望完全不使用缓存数据而直接从服务器获取。可通过 `queryClient.getQueryState` 获取源查询的详细信息(包括 `state.dataUpdatedAt` 时间戳),据此判断数据是否足够新鲜:
+
+[//]: # '示例8'
+
+```tsx
+const result = useQuery({
+ queryKey: ['todo', todoId],
+ queryFn: () => fetch(`/todos/${todoId}`),
+ initialData: () => {
+ // 获取查询状态
+ const state = queryClient.getQueryState(['todos'])
+
+ // 如果查询存在且数据不早于 10 秒...
+ if (state && Date.now() - state.dataUpdatedAt <= 10 * 1000) {
+ // 返回单个待办项
+ return state.data.find((d) => d.id === todoId)
+ }
+
+ // 否则返回 undefined 并从硬加载状态获取!
+ },
+})
+```
+
+[//]: # '示例8'
+[//]: # '材料'
+
+## 延伸阅读
+
+关于 `Initial Data` 与 `Placeholder Data` 的对比,请参阅[社区资源](../community/tkdodos-blog.md#9-placeholder-and-initial-data-in-react-query)。
+
+[//]: # '材料'
diff --git a/docs/zh-hans/framework/react/guides/invalidations-from-mutations.md b/docs/zh-hans/framework/react/guides/invalidations-from-mutations.md
new file mode 100644
index 00000000000..919c7f5b05a
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/invalidations-from-mutations.md
@@ -0,0 +1,43 @@
+---
+source-updated-at: '2025-03-18T08:45:11.000Z'
+translation-updated-at: '2025-05-06T04:12:43.101Z'
+id: invalidations-from-mutations
+title: 从变更中失效
+---
+
+## 变更触发的失效机制
+
+仅使查询失效只是成功的一半,而明确**何时**触发失效才是关键。通常,当应用中的某个变更 (mutation) 成功执行时,极有可能存在与之关联的查询需要被标记为失效状态,甚至重新获取数据以反映变更带来的新变化。
+
+例如,假设我们有一个用于提交新待办事项的变更操作:
+
+[//]: # '示例'
+
+```tsx
+const mutation = useMutation({ mutationFn: postTodo })
+```
+
+[//]: # '示例'
+
+当 `postTodo` 变更成功执行后,我们通常希望所有 `todos` 查询都失效并重新获取,以展示新增的待办事项。为此,可以利用 `useMutation` 的 `onSuccess` 配置项配合查询客户端 (query client) 的 `invalidateQueries` 方法实现:
+
+[//]: # '示例2'
+
+```tsx
+import { useMutation, useQueryClient } from '@tanstack/react-query'
+
+const queryClient = useQueryClient()
+
+// 当此变更成功时,使所有包含 `todos` 或 `reminders` 查询键的查询失效
+const mutation = useMutation({
+ mutationFn: addTodo,
+ onSuccess: () => {
+ queryClient.invalidateQueries({ queryKey: ['todos'] })
+ queryClient.invalidateQueries({ queryKey: ['reminders'] })
+ },
+})
+```
+
+[//]: # '示例2'
+
+您可以通过 [`useMutation` 钩子](./mutations.md) 提供的任意回调函数来配置失效触发逻辑。
diff --git a/docs/zh-hans/framework/react/guides/migrating-to-react-query-3.md b/docs/zh-hans/framework/react/guides/migrating-to-react-query-3.md
new file mode 100644
index 00000000000..0dde03e9db1
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/migrating-to-react-query-3.md
@@ -0,0 +1,543 @@
+---
+source-updated-at: '2025-03-18T08:45:11.000Z'
+translation-updated-at: '2025-05-06T04:15:18.467Z'
+id: migrating-to-react-query-3
+title: 迁移到 v3
+---
+
+以下是翻译内容:
+
+React Query 的早期版本已经非常出色,为库带来了许多令人惊叹的新特性、更多魔法以及整体上更优的体验。它们也推动了该库的大规模采用,同时为库带来了大量优化建议(问题/贡献),并揭示了一些需要进一步打磨以使库更完善的地方。v3 版本正是这些打磨的成果。
+
+## 概述
+
+- 更具扩展性和可测试性的缓存配置
+- 更好的服务端渲染 (SSR) 支持
+- 随处可用的数据延迟(原 usePaginatedQuery)功能
+- 双向无限查询 (Infinite Queries)
+- 查询数据选择器 (Query data selectors)!
+- 使用前可完全配置查询和/或变更的默认选项
+- 更细粒度的可选渲染优化
+- 新增 `useQueries` 钩子!(支持可变长度的并行查询执行)
+- `useIsFetching()` 钩子支持查询过滤器!
+- 变更操作的重试/离线/重放支持
+- 在 React 外部观察查询/变更
+- 可在任意位置使用 React Query 的核心逻辑!
+- 通过 `react-query/devtools` 集成的开发者工具
+- 缓存持久化至 web 存储(实验性功能,通过 `react-query/persistQueryClient-experimental` 和 `react-query/createWebStoragePersistor-experimental` 实现)
+
+## 重大变更
+
+### `QueryCache` 已被拆分为 `QueryClient` 和底层的 `QueryCache` 及 `MutationCache` 实例
+
+`QueryCache` 包含所有查询,`MutationCache` 包含所有变更,而 `QueryClient` 可用于设置配置并与它们交互。
+
+这带来了一些优势:
+
+- 允许不同类型的缓存
+- 不同配置的多个客户端可以共享同一个缓存
+- 客户端可用于跟踪查询,这在 SSR 上实现共享缓存时非常有用
+- 客户端 API 更专注于通用场景
+- 更容易测试各个组件
+
+创建 `new QueryClient()` 时,如果没有提供,则会自动创建 `QueryCache` 和 `MutationCache`。
+
+```tsx
+import { QueryClient } from 'react-query'
+
+const queryClient = new QueryClient()
+```
+
+### `ReactQueryConfigProvider` 和 `ReactQueryCacheProvider` 已被 `QueryClientProvider` 取代
+
+现在可以在 `QueryClient` 中指定查询和变更的默认选项:
+
+**注意:现在使用 defaultOptions 而非 defaultConfig**
+
+```tsx
+const queryClient = new QueryClient({
+ defaultOptions: {
+ queries: {
+ // 查询选项
+ },
+ mutations: {
+ // 变更选项
+ },
+ },
+})
+```
+
+`QueryClientProvider` 组件现在用于将 `QueryClient` 连接到你的应用:
+
+```tsx
+import { QueryClient, QueryClientProvider } from 'react-query'
+
+const queryClient = new QueryClient()
+
+function App() {
+ return ...
+}
+```
+
+### 默认的 `QueryCache` 已移除。这次是真的!
+
+如之前弃用通知所述,主包中不再创建或导出默认的 `QueryCache`。你必须通过 `new QueryClient()` 或 `new QueryCache()`(然后可以传递给 `new QueryClient({ queryCache })`)自行创建。
+
+### 已移除废弃的 `makeQueryCache` 工具函数
+
+虽然等待已久,但它终于被移除了 :)
+
+### `QueryCache.prefetchQuery()` 已移至 `QueryClient.prefetchQuery()`
+
+新的 `QueryClient.prefetchQuery()` 函数是异步的,但不会返回查询的数据。如果需要数据,请使用新的 `QueryClient.fetchQuery()` 函数。
+
+```tsx
+// 预取查询:
+await queryClient.prefetchQuery('posts', fetchPosts)
+
+// 获取查询:
+try {
+ const data = await queryClient.fetchQuery('posts', fetchPosts)
+} catch (error) {
+ // 错误处理
+}
+```
+
+### `ReactQueryErrorResetBoundary` 和 `QueryCache.resetErrorBoundaries()` 已被 `QueryErrorResetBoundary` 和 `useQueryErrorResetBoundary()` 取代。
+
+这些新功能提供了与之前相同的体验,但增加了选择要重置的组件树的控制能力。更多信息请参阅:
+
+- [QueryErrorResetBoundary](../reference/QueryErrorResetBoundary.md)
+- [useQueryErrorResetBoundary](../reference/useQueryErrorResetBoundary.md)
+
+### `QueryCache.getQuery()` 已被 `QueryCache.find()` 取代
+
+现在应使用 `QueryCache.find()` 从缓存中查找单个查询。
+
+### `QueryCache.getQueries()` 已移至 `QueryCache.findAll()`
+
+现在应使用 `QueryCache.findAll()` 从缓存中查找多个查询。
+
+### `QueryCache.isFetching` 已移至 `QueryClient.isFetching()`
+
+**注意:现在是一个函数而非属性**
+
+### `useQueryCache` 钩子已被 `useQueryClient` 钩子取代
+
+它返回组件树中提供的 `queryClient`,除了重命名外基本无需调整。
+
+### 查询键的部分不再自动展开到查询函数中
+
+现在推荐使用内联函数将参数传递给查询函数:
+
+```tsx
+// 旧方式
+useQuery(['post', id], (_key, id) => fetchPost(id))
+
+// 新方式
+useQuery(['post', id], () => fetchPost(id))
+```
+
+如果仍坚持不使用内联函数,可以使用新传递的 `QueryFunctionContext`:
+
+```tsx
+useQuery(['post', id], (context) => fetchPost(context.queryKey[1]))
+```
+
+### 无限查询的页面参数现在通过 `QueryFunctionContext.pageParam` 传递
+
+之前它们是作为查询函数的最后一个查询键参数添加的,但这在某些模式下被证明存在问题。
+
+```tsx
+// 旧方式
+useInfiniteQuery(['posts'], (_key, pageParam = 0) => fetchPosts(pageParam))
+
+// 新方式
+useInfiniteQuery(['posts'], ({ pageParam = 0 }) => fetchPosts(pageParam))
+```
+
+### usePaginatedQuery() 已被移除,改用 `keepPreviousData` 选项
+
+新的 `keepPreviousData` 选项可用于 `useQuery` 和 `useInfiniteQuery`,将对数据产生相同的"滞后"效果:
+
+```tsx
+import { useQuery } from 'react-query'
+
+function Page({ page }) {
+ const { data } = useQuery(['page', page], fetchPage, {
+ keepPreviousData: true,
+ })
+}
+```
+
+### useInfiniteQuery() 现在支持双向操作
+
+`useInfiniteQuery()` 接口已变更,完全支持双向无限列表。
+
+- `options.getFetchMore` 已重命名为 `options.getNextPageParam`
+- `queryResult.canFetchMore` 已重命名为 `queryResult.hasNextPage`
+- `queryResult.fetchMore` 已重命名为 `queryResult.fetchNextPage`
+- `queryResult.isFetchingMore` 已重命名为 `queryResult.isFetchingNextPage`
+- 新增 `options.getPreviousPageParam` 选项
+- 新增 `queryResult.hasPreviousPage` 属性
+- 新增 `queryResult.fetchPreviousPage` 属性
+- 新增 `queryResult.isFetchingPreviousPage`
+- 无限查询的 `data` 现在是一个包含 `pages` 和用于获取这些页面的 `pageParams` 的对象:`{ pages: [data, data, data], pageParams: [...]}`
+
+单向操作:
+
+```tsx
+const { data, fetchNextPage, hasNextPage, isFetchingNextPage } =
+ useInfiniteQuery(
+ 'projects',
+ ({ pageParam = 0 }) => fetchProjects(pageParam),
+ {
+ getNextPageParam: (lastPage, pages) => lastPage.nextCursor,
+ },
+ )
+```
+
+双向操作:
+
+```tsx
+const {
+ data,
+ fetchNextPage,
+ fetchPreviousPage,
+ hasNextPage,
+ hasPreviousPage,
+ isFetchingNextPage,
+ isFetchingPreviousPage,
+} = useInfiniteQuery(
+ 'projects',
+ ({ pageParam = 0 }) => fetchProjects(pageParam),
+ {
+ getNextPageParam: (lastPage, pages) => lastPage.nextCursor,
+ getPreviousPageParam: (firstPage, pages) => firstPage.prevCursor,
+ },
+)
+```
+
+反向单向操作:
+
+```tsx
+const { data, fetchNextPage, hasNextPage, isFetchingNextPage } =
+ useInfiniteQuery(
+ 'projects',
+ ({ pageParam = 0 }) => fetchProjects(pageParam),
+ {
+ select: (data) => ({
+ pages: [...data.pages].reverse(),
+ pageParams: [...data.pageParams].reverse(),
+ }),
+ getNextPageParam: (lastPage, pages) => lastPage.nextCursor,
+ },
+ )
+```
+
+### 无限查询数据现在包含用于获取这些页面的页面数组和 pageParams
+
+这使得操作数据和页面参数更加容易,例如,移除第一页数据及其参数:
+
+```tsx
+queryClient.setQueryData(['projects'], (data) => ({
+ pages: data.pages.slice(1),
+ pageParams: data.pageParams.slice(1),
+}))
+```
+
+### useMutation 现在返回一个对象而非数组
+
+虽然旧方式让我们想起了初次发现 `useState` 时的温暖感觉,但这种感觉并未持续太久。现在变更返回的是一个单独的对象。
+
+```tsx
+// 旧方式:
+const [mutate, { status, reset }] = useMutation()
+
+// 新方式:
+const { mutate, status, reset } = useMutation()
+```
+
+### `mutation.mutate` 不再返回 promise
+
+- `[mutate]` 变量已变更为 `mutation.mutate` 函数
+- 新增 `mutation.mutateAsync` 函数
+
+我们收到了很多关于此行为的疑问,因为用户期望 promise 能像常规 promise 一样工作。
+
+因此,`mutate` 函数现在被拆分为 `mutate` 和 `mutateAsync` 函数。
+
+`mutate` 函数可在使用回调时使用:
+
+```tsx
+const { mutate } = useMutation({ mutationFn: addTodo })
+
+mutate('todo', {
+ onSuccess: (data) => {
+ console.log(data)
+ },
+ onError: (error) => {
+ console.error(error)
+ },
+ onSettled: () => {
+ console.log('settled')
+ },
+})
+```
+
+`mutateAsync` 函数可在使用 async/await 时使用:
+
+```tsx
+const { mutateAsync } = useMutation({ mutationFn: addTodo })
+
+try {
+ const data = await mutateAsync('todo')
+ console.log(data)
+} catch (error) {
+ console.error(error)
+} finally {
+ console.log('settled')
+}
+```
+
+### useQuery 的对象语法现在使用简化的配置:
+
+```tsx
+// 旧方式:
+useQuery({
+ queryKey: 'posts',
+ queryFn: fetchPosts,
+ config: { staleTime: Infinity },
+})
+
+// 新方式:
+useQuery({
+ queryKey: 'posts',
+ queryFn: fetchPosts,
+ staleTime: Infinity,
+})
+```
+
+### 如果设置,QueryOptions.enabled 选项必须是布尔值(`true`/`false`)
+
+`enabled` 查询选项现在仅在值为 `false` 时禁用查询。
+如果需要,可以使用 `!!userId` 或 `Boolean(userId)` 进行转换,如果传递了非布尔值,将抛出错误。
+
+### 已移除 QueryOptions.initialStale 选项
+
+`initialStale` 查询选项已被移除,初始数据现在被视为常规数据。
+这意味着如果提供了 `initialData`,查询默认会在挂载时重新获取。
+如果不希望立即重新获取,可以定义 `staleTime`。
+
+### `QueryOptions.forceFetchOnMount` 选项已被 `refetchOnMount: 'always'` 取代
+
+老实说,我们积累了太多 `refetchOn____` 选项,这应该能清理一下。
+
+### `QueryOptions.refetchOnMount` 选项现在仅适用于其父组件而非所有查询观察者
+
+当 `refetchOnMount` 设置为 `false` 时,会阻止任何额外组件在挂载时重新获取。
+在版本 3 中,仅设置了该选项的组件不会在挂载时重新获取。
+
+### 已移除 `QueryOptions.queryFnParamsFilter`,改用新的 `QueryFunctionContext` 对象
+
+`queryFnParamsFilter` 选项已被移除,因为查询函数现在接收 `QueryFunctionContext` 对象而非查询键。
+
+由于 `QueryFunctionContext` 也包含查询键,参数仍可在查询函数内部进行过滤。
+
+### `QueryOptions.notifyOnStatusChange` 选项已被新的 `notifyOnChangeProps` 和 `notifyOnChangePropsExclusions` 选项取代
+
+通过这些新选项,可以更精细地配置组件应在何时重新渲染。
+
+仅在 `data` 或 `error` 属性变更时重新渲染:
+
+```tsx
+import { useQuery } from 'react-query'
+
+function User() {
+ const { data } = useQuery(['user'], fetchUser, {
+ notifyOnChangeProps: ['data', 'error'],
+ })
+ return 用户名: {data.username}
+}
+```
+
+防止 `isStale` 属性变更时重新渲染:
+
+```tsx
+import { useQuery } from 'react-query'
+
+function User() {
+ const { data } = useQuery(['user'], fetchUser, {
+ notifyOnChangePropsExclusions: ['isStale'],
+ })
+ return 用户名: {data.username}
+}
+```
+
+### `QueryResult.clear()` 函数已重命名为 `QueryResult.remove()`
+
+虽然它被称为 `clear`,但实际上只是将查询从缓存中移除。新名称更符合其功能。
+
+### `QueryResult.updatedAt` 属性已拆分为 `QueryResult.dataUpdatedAt` 和 `QueryResult.errorUpdatedAt` 属性
+
+因为数据和错误可以同时存在,`updatedAt` 属性被拆分为 `dataUpdatedAt` 和 `errorUpdatedAt`。
+
+### `setConsole()` 已被新的 `setLogger()` 函数取代
+
+```tsx
+import { setLogger } from 'react-query'
+
+// 使用 Sentry 记录
+setLogger({
+ error: (error) => {
+ Sentry.captureException(error)
+ },
+})
+
+// 使用 Winston 记录
+setLogger(winston.createLogger())
+```
+
+### React Native 不再需要覆盖记录器
+
+为了防止查询失败时在 React Native 中显示错误屏幕,之前需要手动更改控制台:
+
+```tsx
+import { setConsole } from 'react-query'
+
+setConsole({
+ log: console.log,
+ warn: console.warn,
+ error: console.warn,
+})
+```
+
+在版本 3 中,当在 React Native 中使用 React Query 时会自动完成此操作。
+
+### TypeScript
+
+#### `QueryStatus` 已从 [枚举](https://www.typescriptlang.org/docs/handbook/enums.html#string-enums) 变更为 [联合类型](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types)
+
+因此,如果你曾将查询或变更的 status 属性与 QueryStatus 枚举属性进行比较,现在需要将其与枚举先前为每个属性保存的字符串字面量进行比较。
+
+因此,你需要将枚举属性更改为它们等效的字符串字面量,如下所示:
+
+- `QueryStatus.Idle` -> `'idle'`
+- `QueryStatus.Loading` -> `'loading'`
+- `QueryStatus.Error` -> `'error'`
+- `QueryStatus.Success` -> `'success'`
+
+以下是你需要进行的更改示例:
+
+```tsx
+- import { useQuery, QueryStatus } from 'react-query'; // [!code --]
++ import { useQuery } from 'react-query'; // [!code ++]
+
+const { data, status } = useQuery(['post', id], () => fetchPost(id))
+
+- if (status === QueryStatus.Loading) { // [!code --]
++ if (status === 'loading') { // [!code ++]
+ ...
+}
+
+- if (status === QueryStatus.Error) { // [!code --]
++ if (status === 'error') { // [!code ++]
+ ...
+}
+```
+
+## 新功能
+
+#### 查询数据选择器 (Query Data Selectors)
+
+`useQuery` 和 `useInfiniteQuery` 钩子现在具有 `select` 选项,可以选择或转换查询结果的部分内容。
+
+```tsx
+import { useQuery } from 'react-query'
+
+function User() {
+ const { data } = useQuery(['user'], fetchUser, {
+ select: (user) => user.username,
+ })
+ return 用户名: {data}
+}
+```
+
+将 `notifyOnChangeProps` 选项设置为 `['data', 'error']`,以仅在所选数据变更时重新渲染。
+
+#### useQueries() 钩子,用于可变长度的并行查询执行
+
+希望能在循环中运行 `useQuery`?钩子规则说不可以,但有了新的 `useQueries()` 钩子,你可以!
+
+```tsx
+import { useQueries } from 'react-query'
+
+function Overview() {
+ const results = useQueries([
+ { queryKey: ['post', 1], queryFn: fetchPost },
+ { queryKey: ['post', 2], queryFn: fetchPost },
+ ])
+ return (
+
+ {results.map(({ data }) => data && {data.title}) )}
+
+ )
+}
+```
+
+#### 重试/离线变更
+
+默认情况下,React Query 不会在错误时重试变更,但可以通过 `retry` 选项实现:
+
+```tsx
+const mutation = useMutation({
+ mutationFn: addTodo,
+ retry: 3,
+})
+```
+
+如果因设备离线导致变更失败,它们将在设备重新连接时按相同顺序重试。
+
+#### 持久化变更
+
+变更现在可以持久化到存储中,并在稍后恢复。更多信息请参阅变更文档。
+
+#### QueryObserver
+
+`QueryObserver` 可用于创建和/或观察查询:
+
+```tsx
+const observer = new QueryObserver(queryClient, { queryKey: 'posts' })
+
+const unsubscribe = observer.subscribe((result) => {
+ console.log(result)
+ unsubscribe()
+})
+```
+
+#### InfiniteQueryObserver
+
+`InfiniteQueryObserver` 可用于创建和/或观察无限查询:
+
+```tsx
+const observer = new InfiniteQueryObserver(queryClient, {
+ queryKey: 'posts',
+ queryFn: fetchPosts,
+ getNextPageParam: (lastPage, allPages) => lastPage.nextCursor,
+ getPreviousPageParam: (firstPage, allPages) => firstPage.prevCursor,
+})
+
+const unsubscribe = observer.subscribe((result) => {
+ console.log(result)
+ unsubscribe()
+})
+```
+
+#### QueriesObserver
+
+`QueriesObserver` 可用于创建和/或观察多个查询:
+
+```tsx
+const observer = new QueriesObserver(queryClient, [
+ { queryKey: ['post', 1], queryFn: fetch
+```
diff --git a/docs/zh-hans/framework/react/guides/migrating-to-react-query-4.md b/docs/zh-hans/framework/react/guides/migrating-to-react-query-4.md
new file mode 100644
index 00000000000..6ced895189a
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/migrating-to-react-query-4.md
@@ -0,0 +1,389 @@
+---
+source-updated-at: '2025-03-31T09:06:11.000Z'
+translation-updated-at: '2025-05-06T04:15:18.700Z'
+id: migrating-to-react-query-4
+title: 迁移到 v4
+---
+
+## 重大变更
+
+v4 是一个主要版本,需要注意以下破坏性变更:
+
+### react-query 现已更名为 @tanstack/react-query
+
+需要卸载/安装依赖并更改导入路径:
+
+```
+npm uninstall react-query
+npm install @tanstack/react-query
+npm install @tanstack/react-query-devtools
+```
+
+```tsx
+- import { useQuery } from 'react-query' // [!code --]
+- import { ReactQueryDevtools } from 'react-query/devtools' // [!code --]
+
++ import { useQuery } from '@tanstack/react-query' // [!code ++]
++ import { ReactQueryDevtools } from '@tanstack/react-query-devtools' // [!code ++]
+```
+
+#### 代码迁移工具 (Codemod)
+
+为简化导入迁移,v4 提供了代码迁移工具。
+
+> 该工具会尽力协助迁移破坏性变更,但请仔细检查生成代码!某些边缘情况可能无法被工具识别,请留意日志输出。
+
+可通过以下命令之一运行迁移:
+
+针对 `.js` 或 `.jsx` 文件:
+
+```
+npx jscodeshift ./path/to/src/ \
+ --extensions=js,jsx \
+ --transform=./node_modules/@tanstack/react-query/codemods/v4/replace-import-specifier.js
+```
+
+针对 `.ts` 或 `.tsx` 文件:
+
+```
+npx jscodeshift ./path/to/src/ \
+ --extensions=ts,tsx \
+ --parser=tsx \
+ --transform=./node_modules/@tanstack/react-query/codemods/v4/replace-import-specifier.js
+```
+
+注意:对于 `TypeScript` 必须使用 `tsx` 作为解析器,否则迁移可能无法正确应用!
+
+**注意:** 迁移后可能会破坏代码格式,请记得运行 `prettier` 和/或 `eslint` 进行格式化。
+
+**注意:** 该工具仅修改导入语句——仍需手动安装独立的开发工具包。
+
+### 查询键 (Query Keys) 和变更键 (Mutation Keys) 必须为数组
+
+v3 中查询键和变更键可以是字符串或数组。React Query 内部始终使用数组键,有时会暴露给使用者。例如在 `queryFn` 中,为便于使用[默认查询函数](./default-query-function.md),获取的键始终是数组。
+
+但此设计未在所有 API 中贯彻。例如使用[查询过滤器](./filters.md)的 `predicate` 函数时,获取的是原始查询键。若混合使用数组和字符串键,此类函数将难以工作。全局回调也存在同样问题。
+
+为统一所有 API,现强制要求所有键必须为数组:
+
+```tsx
+;-useQuery('todos', fetchTodos) + // [!code --]
+ useQuery(['todos'], fetchTodos) // [!code ++]
+```
+
+#### 代码迁移工具
+
+为简化迁移,提供了专用迁移工具。
+
+> 该工具会尽力协助迁移,但请仔细检查生成代码!某些边缘情况可能无法被工具识别,请留意日志输出。
+
+可通过以下命令之一运行迁移:
+
+针对 `.js` 或 `.jsx` 文件:
+
+```
+npx jscodeshift ./path/to/src/ \
+ --extensions=js,jsx \
+ --transform=./node_modules/@tanstack/react-query/codemods/v4/key-transformation.js
+```
+
+针对 `.ts` 或 `.tsx` 文件:
+
+```
+npx jscodeshift ./path/to/src/ \
+ --extensions=ts,tsx \
+ --parser=tsx \
+ --transform=./node_modules/@tanstack/react-query/codemods/v4/key-transformation.js
+```
+
+注意:对于 `TypeScript` 必须使用 `tsx` 作为解析器。
+
+**注意:** 迁移后可能会破坏代码格式,请记得运行 `prettier` 和/或 `eslint` 进行格式化。
+
+### 移除 idle 状态
+
+为支持更好的离线功能引入新的[获取状态 (fetchStatus)](./queries.md#fetchstatus)后,`idle` 状态变得冗余,因为 `fetchStatus: 'idle'` 能更准确地描述相同状态。详见[为何需要两种状态](./queries.md#why-two-different-states)。
+
+主要影响尚未获取任何 `data` 的 `disabled` 查询,这些查询之前处于 `idle` 状态:
+
+```tsx
+- status: 'idle' // [!code --]
++ status: 'loading' // [!code ++]
++ fetchStatus: 'idle' // [!code ++]
+```
+
+另请参阅[依赖查询指南](./dependent-queries.md)
+
+#### 禁用查询 (disabled queries)
+
+因此变更,禁用查询(包括临时禁用)将初始处于 `loading` 状态。为简化迁移,特别是需要显示加载指示器时,可检查 `isInitialLoading` 而非 `isLoading`:
+
+```tsx
+;-isLoading + // [!code --]
+ isInitialLoading // [!code ++]
+```
+
+参见[禁用查询指南](./disabling-queries.md#isInitialLoading)
+
+### `useQueries` 新 API
+
+`useQueries` 钩子现在接受包含 `queries` 属性的对象作为输入。`queries` 属性值是一个查询数组(该数组与 v3 中直接传入 `useQueries` 的数组相同)。
+
+```tsx
+;-useQueries([
+ { queryKey1, queryFn1, options1 },
+ { queryKey2, queryFn2, options2 },
+]) + // [!code --]
+ useQueries({
+ queries: [
+ { queryKey1, queryFn1, options1 },
+ { queryKey2, queryFn2, options2 },
+ ],
+ }) // [!code ++]
+```
+
+### 成功查询中 undefined 不再作为合法缓存值
+
+为实现通过返回 `undefined` 中止更新,现规定 `undefined` 不是合法缓存值。这与 React Query 其他设计一致,例如从[初始数据函数](./initial-query-data.md#initial-data-function)返回 `undefined` 也不会设置数据。
+
+此外,在 `queryFn` 中添加日志容易产生 `Promise`:
+
+```tsx
+useQuery(['key'], () =>
+ axios.get(url).then((result) => console.log(result.data)),
+)
+```
+
+现在类型层面已禁止此操作;运行时 `undefined` 会转换为 _失败的 Promise_,意味着会收到 `error`,开发模式下还会在控制台记录此错误。
+
+### 默认情况下查询和变更需要网络连接
+
+请阅读关于在线/离线支持的[新功能公告](#proper-offline-support)及专用[网络模式](./network-mode.md)页面。
+
+虽然 React Query 是可用于任何 Promise 的异步状态管理器,但最常用于数据获取场景。因此默认情况下,若无网络连接,查询和变更将处于 `paused` 状态。如需恢复之前行为,可全局设置 `networkMode: offlineFirst`:
+
+```tsx
+new QueryClient({
+ defaultOptions: {
+ queries: {
+ networkMode: 'offlineFirst',
+ },
+ mutations: {
+ networkMode: 'offlineFirst',
+ },
+ },
+})
+```
+
+### `notifyOnChangeProps` 不再接受 `"tracked"` 值
+
+`notifyOnChangeProps` 选项不再接受 `"tracked"` 值,改为默认启用属性跟踪。所有使用 `notifyOnChangeProps: "tracked"` 的查询应移除此选项。
+
+如需模拟 v3 默认行为(查询变化时重新渲染),现可通过设置 `notifyOnChangeProps: "all"` 来禁用智能跟踪优化。
+
+### 移除 `notifyOnChangePropsExclusion`
+
+v4 中 `notifyOnChangeProps` 默认采用 v3 的 `"tracked"` 行为而非 `undefined`。由于 `"tracked"` 现为默认行为,此配置选项已无存在必要。
+
+### `cancelRefetch` 行为统一
+
+`cancelRefetch` 选项现在可传递给所有主动获取查询的方法:
+
+- `queryClient.refetchQueries`
+- `queryClient.invalidateQueries`
+- `queryClient.resetQueries`
+- `useQuery` 返回的 `refetch`
+- `useInfiniteQuery` 返回的 `fetchNextPage` 和 `fetchPreviousPage`
+
+除 `fetchNextPage` 和 `fetchPreviousPage` 外,此标志原默认值为 `false`,这会导致不一致问题:若已有缓慢请求在进行中,调用 `refetchQueries` 或 `invalidateQueries` 可能无法获取最新结果,因为此次重获取会被跳过。
+
+我们认为代码主动触发的查询重获取应默认重启请求。
+
+因此现在所有相关方法的此标志默认值改为 _true_。这也意味着连续两次调用 `refetchQueries` 而不等待时,会取消第一次请求并重启第二次请求:
+
+```
+queryClient.refetchQueries({ queryKey: ['todos'] })
+// 这将中止前次重获取并启动新请求
+queryClient.refetchQueries({ queryKey: ['todos'] })
+```
+
+可通过显式传递 `cancelRefetch:false` 禁用此行为:
+
+```
+queryClient.refetchQueries({ queryKey: ['todos'] })
+// 前次重获取不会被中止——此次调用会被忽略
+queryClient.refetchQueries({ queryKey: ['todos'] }, { cancelRefetch: false })
+```
+
+> 注意:自动触发的获取(如查询挂载或窗口聚焦重获取)行为不变。
+
+### 查询过滤器 (Query Filters)
+
+[查询过滤器](./filters.md)是匹配查询的条件对象。历史上过滤器选项多为布尔标志组合,但这可能导致矛盾状态。例如:
+
+```
+active?: boolean
+ - true 时匹配活跃查询
+ - false 时匹配非活跃查询
+inactive?: boolean
+ - true 时匹配非活跃查询
+ - false 时匹配活跃查询
+```
+
+这些标志组合使用时效果不佳,因为它们互斥。双 `false` 配置理论上应匹配所有查询或没有查询,语义不明确。
+
+v4 中将这些过滤器合并为单一选项以明确意图:
+
+```tsx
+- active?: boolean // [!code --]
+- inactive?: boolean // [!code --]
++ type?: 'active' | 'inactive' | 'all' // [!code ++]
+```
+
+默认值为 `all`,可选择仅匹配 `active` 或 `inactive` 查询。
+
+#### refetchActive / refetchInactive
+
+[queryClient.invalidateQueries](../../../reference/QueryClient.md#queryclientinvalidatequeries) 原有两个类似标志:
+
+```
+refetchActive: Boolean
+ - 默认 true
+ - false 时,匹配重获取条件且正通过 useQuery 等渲染的活跃查询不会在后台重获取,仅标记为失效
+refetchInactive: Boolean
+ - 默认 false
+ - true 时,匹配重获取条件且未渲染的非活跃查询会标记为失效并在后台重获取
+```
+
+出于相同原因,这些标志也被合并:
+
+```tsx
+- refetchActive?: boolean // [!code --]
+- refetchInactive?: boolean // [!code --]
++ refetchType?: 'active' | 'inactive' | 'all' | 'none' // [!code ++]
+```
+
+此标志默认 `active`(因 `refetchActive` 原默认 `true`)。为支持完全不重获取的场景,新增 `none` 选项。
+
+### `setQueryData` 不再触发 `onSuccess`
+
+此前设计令许多人困惑:若在 `onSuccess` 内调用 `setQueryData` 会导致无限循环。与 `staleTime` 结合使用时也常引发问题——若数据仅从缓存读取,`onSuccess` 不会被调用。
+
+与 `onError` 和 `onSettled` 类似,`onSuccess` 回调现与请求绑定。无请求 -> 无回调。
+
+如需监听 `data` 字段变化,建议使用 `useEffect` 并将 `data` 加入依赖数组。React Query 通过结构共享确保数据稳定,效果函数不会在每次后台重获取时执行,仅在数据实际变化时触发:
+
+```
+const { data } = useQuery({ queryKey, queryFn })
+React.useEffect(() => mySideEffectHere(data), [data])
+```
+
+### `persistQueryClient` 及相关持久化插件结束实验状态并更名
+
+插件 `createWebStoragePersistor` 和 `createAsyncStoragePersistor` 分别更名为 [`createSyncStoragePersister`](../plugins/createSyncStoragePersister.md) 和 [`createAsyncStoragePersister`](../plugins/createAsyncStoragePersister.md)。`persistQueryClient` 中的 `Persistor` 接口也更名为 `Persister`。更名动机参见[此讨论](https://english.stackexchange.com/questions/206893/persister-or-persistor)。
+
+由于这些插件已结束实验状态,导入路径也已更新:
+
+```tsx
+- import { persistQueryClient } from 'react-query/persistQueryClient-experimental' // [!code --]
+- import { createWebStoragePersistor } from 'react-query/createWebStoragePersistor-experimental' // [!code --]
+- import { createAsyncStoragePersistor } from 'react-query/createAsyncStoragePersistor-experimental' // [!code --]
+
++ import { persistQueryClient } from '@tanstack/react-query-persist-client' // [!code ++]
++ import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister' // [!code ++]
++ import { createAsyncStoragePersister } from '@tanstack/query-async-storage-persister' // [!code ++]
+```
+
+### 不再支持 Promise 的 `cancel` 方法
+
+[旧版 `cancel` 方法](./query-cancellation.md#old-cancel-function)允许在 Promise 上定义 `cancel` 函数以实现查询取消,现已被移除。建议使用[新版 API](./query-cancellation.md)(v3.30.0 引入),其内部使用 [`AbortController` API](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) 并提供 [`AbortSignal` 实例](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal)支持查询取消。
+
+### TypeScript
+
+现在需要 TypeScript v4.1 或更高版本
+
+### 支持的浏览器
+
+v4 起 React Query 针对现代浏览器优化。我们已更新 browserslist 配置以生成更现代、高效且更小的包。具体要求参见[安装说明](../../installation#requirements)。
+
+### 移除 `setLogger`
+
+原先可通过 `setLogger` 全局修改日志记录器。v4 中此功能改为在创建 `QueryClient` 时通过可选字段配置。
+
+```tsx
+- import { QueryClient, setLogger } from 'react-query'; // [!code --]
++ import { QueryClient } from '@tanstack/react-query'; // [!code ++]
+
+- setLogger(customLogger) // [!code --]
+- const queryClient = new QueryClient(); // [!code --]
++ const queryClient = new QueryClient({ logger: customLogger }) // [!code ++]
+```
+
+### 服务端默认禁用手动垃圾回收
+
+v3 中 React Query 默认缓存查询结果 5 分钟,然后手动垃圾回收。此默认行为也应用于服务端 React Query。
+
+这导致高内存消耗和进程挂起等待垃圾回收完成。v4 中服务端 `cacheTime` 默认改为 `Infinity`,相当于禁用手动垃圾回收(NodeJS 进程会在请求完成后自动清理)。
+
+此变更仅影响服务端 React Query 用户(如 Next.js)。若手动设置 `cacheTime` 则不受影响(但建议保持行为一致)。
+
+### 生产环境日志记录
+
+v4 起,生产环境下 react-query 不再将错误(如获取失败)记录到控制台,因之前常引起困惑。开发模式下错误仍会显示。
+
+### ESM 支持
+
+React Query 现在支持 [package.json `"exports"`](https://nodejs.org/api/packages.html#exports),完全兼容 Node 的原生 CommonJS 和 ESM 解析。预计对多数用户无破坏性影响,但此变更限制只能导入官方支持的入口文件。
+
+### 统一通知事件 (NotifyEvents)
+
+手动订阅 `QueryCache` 始终会收到 `QueryCacheNotifyEvent`,但 `MutationCache` 之前无此设计。现统一行为并调整事件名称:
+
+#### QueryCacheNotifyEvent
+
+```tsx
+- type: 'queryAdded' // [!code --]
++ type: 'added' // [!code ++]
+- type: 'queryRemoved' // [!code --]
++ type: 'removed' // [!code ++]
+- type: 'queryUpdated' // [!code --]
++ type: 'updated' // [!code ++]
+```
+
+#### MutationCacheNotifyEvent
+
+`MutationCacheNotifyEvent` 使用与 `QueryCacheNotifyEvent` 相同的类型。
+
+> 注意:仅当通过 `queryCache.subscribe` 或 `mutationCache.subscribe` 手动订阅缓存时相关
+
+### 移除独立的水合 (hydration) 导出
+
+自 [3.22.0](https://github.com/tannerlinsley/react-query/releases/tag/v3.22.0) 版本起,水合工具已移至 React Query 核心。v3 中仍可从 `react-query/hydration` 导入旧导出,但 v4 中已移除。
+
+```tsx
+- import { dehydrate, hydrate, useHydrate, Hydrate } from 'react-query/hydration' // [!code --]
++ import { dehydrate, hydrate, useHydrate, Hydrate } from '@tanstack/react-query' // [!code ++]
+```
+
+### 移除 `queryClient`、`query` 和 `mutation` 的未公开方法
+
+`QueryClient` 上的 `cancelMutations` 和 `executeMutation` 方法未在文档中说明且内部未使用,故已移除。由于这只是对 `mutationCache` 方法的封装,仍可通过 `executeMutation` 的功能:
+
+```tsx
+- executeMutation< // [!code --]
+- TData = unknown, // [!code --]
+- TError = unknown, // [!code --]
+- TVariables = void, // [!code --]
+- TContext = unknown // [!code --]
+- >( // [!code --]
+- options: MutationOptions // [!code --]
+- ): Promise { // [!code --]
+- return this.mutationCache.build(this, options).execute() // [!code --]
+- } // [!code --]
+```
+
+此外,移除未使用的 `query.setDefaultOptions`。移除 `mutation.cancel` 因其实际未取消请求。
+
+### `src/react` 目录更名为 `src/reactjs`
+
+原先包含从 `react` 模块导入的 `react` 目录在某些 Jest 配置下会导致测试报
diff --git a/docs/zh-hans/framework/react/guides/migrating-to-v5.md b/docs/zh-hans/framework/react/guides/migrating-to-v5.md
new file mode 100644
index 00000000000..3621d166c9f
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/migrating-to-v5.md
@@ -0,0 +1,356 @@
+---
+source-updated-at: '2025-03-19T08:29:27.000Z'
+translation-updated-at: '2025-05-06T04:15:15.834Z'
+id: migrating-to-tanstack-query-5
+title: 迁移到 v5
+---
+
+## 重大变更
+
+v5 是一个主要版本,因此需要注意以下重大变更:
+
+### 仅支持单一对象参数签名
+
+`useQuery` 及相关函数在 TypeScript 中曾有多种重载形式——即函数可以通过不同方式调用。这不仅在类型维护上困难,还需要运行时检查第一和第二参数的类型以正确创建选项。
+
+现在仅支持对象格式:
+
+```tsx
+useQuery(key, fn, options) // [!code --]
+useQuery({ queryKey, queryFn, ...options }) // [!code ++]
+useInfiniteQuery(key, fn, options) // [!code --]
+useInfiniteQuery({ queryKey, queryFn, ...options }) // [!code ++]
+useMutation(fn, options) // [!code --]
+useMutation({ mutationFn, ...options }) // [!code ++]
+useIsFetching(key, filters) // [!code --]
+useIsFetching({ queryKey, ...filters }) // [!code ++]
+useIsMutating(key, filters) // [!code --]
+useIsMutating({ mutationKey, ...filters }) // [!code ++]
+```
+
+```tsx
+queryClient.isFetching(key, filters) // [!code --]
+queryClient.isFetching({ queryKey, ...filters }) // [!code ++]
+queryClient.ensureQueryData(key, filters) // [!code --]
+queryClient.ensureQueryData({ queryKey, ...filters }) // [!code ++]
+queryClient.getQueriesData(key, filters) // [!code --]
+queryClient.getQueriesData({ queryKey, ...filters }) // [!code ++]
+queryClient.setQueriesData(key, updater, filters, options) // [!code --]
+queryClient.setQueriesData({ queryKey, ...filters }, updater, options) // [!code ++]
+queryClient.removeQueries(key, filters) // [!code --]
+queryClient.removeQueries({ queryKey, ...filters }) // [!code ++]
+queryClient.resetQueries(key, filters, options) // [!code --]
+queryClient.resetQueries({ queryKey, ...filters }, options) // [!code ++]
+queryClient.cancelQueries(key, filters, options) // [!code --]
+queryClient.cancelQueries({ queryKey, ...filters }, options) // [!code ++]
+queryClient.invalidateQueries(key, filters, options) // [!code --]
+queryClient.invalidateQueries({ queryKey, ...filters }, options) // [!code ++]
+queryClient.refetchQueries(key, filters, options) // [!code --]
+queryClient.refetchQueries({ queryKey, ...filters }, options) // [!code ++]
+queryClient.fetchQuery(key, fn, options) // [!code --]
+queryClient.fetchQuery({ queryKey, queryFn, ...options }) // [!code ++]
+queryClient.prefetchQuery(key, fn, options) // [!code --]
+queryClient.prefetchQuery({ queryKey, queryFn, ...options }) // [!code ++]
+queryClient.fetchInfiniteQuery(key, fn, options) // [!code --]
+queryClient.fetchInfiniteQuery({ queryKey, queryFn, ...options }) // [!code ++]
+queryClient.prefetchInfiniteQuery(key, fn, options) // [!code --]
+queryClient.prefetchInfiniteQuery({ queryKey, queryFn, ...options }) // [!code ++]
+```
+
+```tsx
+queryCache.find(key, filters) // [!code --]
+queryCache.find({ queryKey, ...filters }) // [!code ++]
+queryCache.findAll(key, filters) // [!code --]
+queryCache.findAll({ queryKey, ...filters }) // [!code ++]
+```
+
+### `queryClient.getQueryData` 现在仅接受 `queryKey` 作为参数
+
+`queryClient.getQueryData` 的参数改为仅接受 `queryKey`:
+
+```tsx
+queryClient.getQueryData(queryKey, filters) // [!code --]
+queryClient.getQueryData(queryKey) // [!code ++]
+```
+
+### `queryClient.getQueryState` 现在仅接受 `queryKey` 作为参数
+
+`queryClient.getQueryState` 的参数改为仅接受 `queryKey`:
+
+```tsx
+queryClient.getQueryState(queryKey, filters) // [!code --]
+queryClient.getQueryState(queryKey) // [!code ++]
+```
+
+#### 代码迁移工具 (Codemod)
+
+为简化重载移除的迁移工作,v5 提供了代码迁移工具。
+
+> 该工具会尽力协助迁移重大变更,但请仔细检查生成的代码!此外,某些边缘情况可能无法被工具识别,请留意日志输出。
+
+如需针对 `.js` 或 `.jsx` 文件运行,请使用以下命令:
+
+```
+npx jscodeshift@latest ./path/to/src/ \
+ --extensions=js,jsx \
+ --transform=./node_modules/@tanstack/react-query/build/codemods/src/v5/remove-overloads/remove-overloads.cjs
+```
+
+如需针对 `.ts` 或 `.tsx` 文件运行,请使用以下命令:
+
+```
+npx jscodeshift@latest ./path/to/src/ \
+ --extensions=ts,tsx \
+ --parser=tsx \
+ --transform=./node_modules/@tanstack/react-query/build/codemods/src/v5/remove-overloads/remove-overloads.cjs
+```
+
+注意:对于 `TypeScript` 文件,必须使用 `tsx` 作为解析器,否则代码迁移工具可能无法正确应用!
+
+**注意:** 应用代码迁移工具可能会破坏代码格式,完成后请务必运行 `prettier` 和/或 `eslint`!
+
+关于代码迁移工具工作原理的说明:
+
+- 一般情况下,我们会寻找理想情况:当第一个参数是对象表达式且包含 "queryKey" 或 "mutationKey" 属性(取决于正在转换的钩子/方法调用)。如果符合此条件,则代码已匹配新签名,工具不会修改。🎉
+- 如果不符合上述条件,工具会检查第一个参数是否为数组表达式或引用数组表达式的标识符。如果是,则将其放入对象表达式中作为第一个参数。
+- 如果可以推断对象参数,工具会尝试将现有属性复制到新创建的对象中。
+- 如果工具无法推断用法,则会在控制台输出消息,包含文件名和代码行号。此时需要手动迁移。
+- 如果转换导致错误,控制台也会显示消息,提示发生意外情况,请手动迁移。
+
+### 移除了 `useQuery`(及 `QueryObserver`)中的回调函数
+
+`onSuccess`、`onError` 和 `onSettled` 已从查询中移除(突变中仍保留)。请参阅 [此 RFC](https://github.com/TanStack/query/discussions/5279) 了解变更动机及替代方案。
+
+### `refetchInterval` 回调函数现在仅接收 `query` 参数
+
+这统一了回调调用方式(`refetchOnWindowFocus`、`refetchOnMount` 和 `refetchOnReconnect` 回调也仅接收查询参数),并修复了当回调获取通过 `select` 转换的数据时的一些类型问题。
+
+```tsx
+- refetchInterval: number | false | ((data: TData | undefined, query: Query) => number | false | undefined) // [!code --]
++ refetchInterval: number | false | ((query: Query) => number | false | undefined) // [!code ++]
+```
+
+仍可通过 `query.state.data` 访问数据,但不会是通过 `select` 转换后的数据。如需访问转换后的数据,可对 `query.state.data` 再次调用转换函数。
+
+### 从 `useQuery` 中移除了 `remove` 方法
+
+此前,`remove` 方法用于从 `queryCache` 中移除查询而不通知观察者。通常用于强制移除不再需要的数据,例如用户注销时。
+
+但当查询仍处于活动状态时这样做没有意义,因为下次重新渲染会触发硬加载状态。
+
+如需移除查询,可使用 `queryClient.removeQueries({queryKey: key})`:
+
+```tsx
+const queryClient = useQueryClient()
+const query = useQuery({ queryKey, queryFn })
+
+query.remove() // [!code --]
+queryClient.removeQueries({ queryKey }) // [!code ++]
+```
+
+### 最低要求的 TypeScript 版本现为 4.7
+
+主要因为修复了一个重要的类型推断问题。详情请参阅 [TypeScript issue](https://github.com/microsoft/TypeScript/issues/43371)。
+
+### 从 `useQuery` 中移除了 `isDataEqual` 选项
+
+此前,该函数用于指示是使用先前的 `data`(`true`)还是新数据(`false`)作为查询的解析数据。
+
+可通过向 `structuralSharing` 传递函数实现相同功能:
+
+```tsx
+ import { replaceEqualDeep } from '@tanstack/react-query'
+
+- isDataEqual: (oldData, newData) => customCheck(oldData, newData) // [!code --]
++ structuralSharing: (oldData, newData) => customCheck(oldData, newData) ? oldData : replaceEqualDeep(oldData, newData) // [!code ++]
+```
+
+### 移除了已弃用的自定义日志记录器
+
+自定义日志记录器在 v4 中已弃用,在此版本中移除。日志记录仅在开发模式下有效,而在此模式下传递自定义日志记录器并无必要。
+
+### 支持的浏览器
+
+我们更新了 browserslist 以生成更现代、性能更好且体积更小的包。要求详见 [此处](../../installation#requirements)。
+
+### 私有类字段和方法
+
+TanStack Query 始终在类中有私有字段和方法,但它们并非真正的私有——仅在 `TypeScript` 中是私有的。现在我们使用 [ECMAScript 私有类特性](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_class_fields),意味着这些字段在运行时真正私有,无法从外部访问。
+
+### 将 `cacheTime` 重命名为 `gcTime`
+
+几乎每个人都误解了 `cacheTime`。它听起来像是"数据缓存的时间",但这是错误的。
+
+只要查询仍在使用,`cacheTime` 就不起作用。仅在查询不再使用时生效。超时后,数据会被"垃圾回收"以避免缓存增长。
+
+`gc` 指"垃圾回收"时间。这更技术性,但在计算机科学中是 [众所周知的缩写]()。
+
+```tsx
+const MINUTE = 1000 * 60;
+
+const queryClient = new QueryClient({
+ defaultOptions: {
+ queries: {
+- cacheTime: 10 * MINUTE, // [!code --]
++ gcTime: 10 * MINUTE, // [!code ++]
+ },
+ },
+})
+```
+
+### `useErrorBoundary` 选项已重命名为 `throwOnError`
+
+为使 `useErrorBoundary` 选项更框架无关,并避免与 React 钩子的 "`use`" 前缀和 "ErrorBoundary" 组件名称混淆,现重命名为 `throwOnError` 以更准确反映其功能。
+
+### TypeScript:`Error` 现在是错误的默认类型而非 `unknown`
+
+尽管在 JavaScript 中可以 `throw` 任何内容(这使得 `unknown` 是最正确的类型),但几乎总是抛出 `Error`(或其子类)。此变更使在 TypeScript 中处理 `error` 字段对大多数情况更简单。
+
+如需抛出非 Error 的内容,现在需自行设置泛型:
+
+```ts
+useQuery({
+ queryKey: ['some-query'],
+ queryFn: async () => {
+ if (Math.random() > 0.5) {
+ throw 'some error'
+ }
+ return 42
+ },
+})
+```
+
+如需全局设置不同类型的错误,请参阅 [TypeScript 指南](../typescript.md#registering-a-global-error)。
+
+### 移除了 eslint `prefer-query-object-syntax` 规则
+
+由于现在唯一支持的语法是对象语法,此规则不再需要。
+
+### 用 `placeholderData` 恒等函数替代 `keepPreviousData`
+
+我们移除了 `keepPreviousData` 选项和 `isPreviousData` 标志,因为它们的功能与 `placeholderData` 和 `isPlaceholderData` 标志基本相同。
+
+为实现与 `keepPreviousData` 相同的功能,我们向 `placeholderData` 添加了先前查询 `data` 作为参数,它接受一个恒等函数。因此只需向 `placeholderData` 提供恒等函数或使用 Tanstack Query 包含的 `keepPreviousData` 函数。
+
+> 注意:`useQueries` 不会在 `placeholderData` 函数中接收 `previousData` 作为参数。这是由于传入数组的查询的动态性质可能导致占位符和 `queryFn` 的结果形状不同。
+
+```tsx
+import {
+ useQuery,
++ keepPreviousData // [!code ++]
+} from "@tanstack/react-query";
+
+const {
+ data,
+- isPreviousData, // [!code --]
++ isPlaceholderData, // [!code ++]
+} = useQuery({
+ queryKey,
+ queryFn,
+- keepPreviousData: true, // [!code --]
++ placeholderData: keepPreviousData // [!code ++]
+});
+```
+
+在 Tanstack Query 的上下文中,恒等函数指始终返回其提供的参数(即数据)而不做更改的函数。
+
+```ts
+useQuery({
+ queryKey,
+ queryFn,
+ placeholderData: (previousData, previousQuery) => previousData, // 与 `keepPreviousData` 行为相同的恒等函数
+})
+```
+
+但此变更有一些注意事项:
+
+- `placeholderData` 会始终进入 `success` 状态,而 `keepPreviousData` 给出先前查询的状态。如果数据成功获取后遇到后台刷新错误,状态可能是 `error`。但由于错误本身未共享,我们决定坚持 `placeholderData` 的行为。
+- `keepPreviousData` 提供先前数据的 `dataUpdatedAt` 时间戳,而使用 `placeholderData` 时 `dataUpdatedAt` 保持为 `0`。如需在屏幕上连续显示该时间戳可能会不便,但可通过 `useEffect` 解决:
+
+ ```ts
+ const [updatedAt, setUpdatedAt] = useState(0)
+
+ const { data, dataUpdatedAt } = useQuery({
+ queryKey: ['projects', page],
+ queryFn: () => fetchProjects(page),
+ })
+
+ useEffect(() => {
+ if (dataUpdatedAt > updatedAt) {
+ setUpdatedAt(dataUpdatedAt)
+ }
+ }, [dataUpdatedAt])
+ ```
+
+### 窗口焦点重新获取不再监听 `focus` 事件
+
+现在仅使用 `visibilitychange` 事件。这是可行的,因为我们仅支持支持 `visibilitychange` 事件的浏览器。这修复了 [此处列出](https://github.com/TanStack/query/pull/4805) 的一系列问题。
+
+### 网络状态不再依赖 `navigator.onLine` 属性
+
+`navigator.onLine` 在基于 Chromium 的浏览器中效果不佳。存在 [许多问题](https://bugs.chromium.org/p/chromium/issues/list?q=navigator.online) 关于误报,导致查询被错误标记为 `offline`。
+
+为避免此问题,我们现在始终以 `online: true` 开始,仅监听 `online` 和 `offline` 事件来更新状态。
+
+这应减少误报的可能性,但对于通过 serviceWorkers 加载的离线应用,可能意味着误报,因为这些应用即使没有互联网连接也能工作。
+
+### 移除自定义 `context` 属性,改用自定义 `queryClient` 实例
+
+在 v4 中,我们引入了向所有 react-query 钩子传递自定义 `context` 的可能性。这在使用微前端时实现了适当的隔离。
+
+然而,`context` 是仅 React 的特性。`context` 所做的只是让我们访问 `queryClient`。我们可以通过允许直接传入自定义 `queryClient` 实现相同的隔离。
+这反过来使其他框架能够以框架无关的方式拥有相同的功能。
+
+```tsx
+import { queryClient } from './my-client'
+
+const { data } = useQuery(
+ {
+ queryKey: ['users', id],
+ queryFn: () => fetch(...),
+- context: customContext // [!code --]
+ },
++ queryClient, // [!code ++]
+)
+```
+
+### 移除 `refetchPage`,改用 `maxPages`
+
+在 v4 中,我们引入了通过 `refetchPage` 函数定义无限查询中要重新获取的页面的可能性。
+
+然而,重新获取所有页面可能导致 UI 不一致。此外,此选项在例如 `queryClient.refetchQueries` 上可用,但仅对无限查询有效,而非"普通"查询。
+
+v5 为无限查询引入了新的 `maxPages` 选项,以限制存储在查询数据中和重新获取的页面数量。此新功能处理了最初为 `refetchPage` 功能识别的用例,而无需相关的问题。
+
+### 新的 `dehydrate` API
+
+传递给 `dehydrate` 的选项已简化。查询和突变始终根据默认函数实现进行脱水。要更改此行为,可以使用移除的布尔选项 `dehydrateMutations` 和 `dehydrateQueries` 的函数等效项 `shouldDehydrateQuery` 或 `shouldDehydrateMutation`。要完全不水合查询/突变,传入 `() => false`。
+
+```tsx
+- dehydrateMutations?: boolean // [!code --]
+- dehydrateQueries?: boolean // [!code --]
+```
+
+### 无限查询现在需要 `initialPageParam`
+
+此前,我们向 `queryFn` 传递 `undefined` 作为 `pageParam`,并且可以在 `queryFn` 函数签名中为 `pageParam` 参数分配默认值。这导致在 `queryCache` 中存储不可序列化的 `undefined`。
+
+现在,必须向无限查询选项显式传递 `initialPageParam`。这将用作第一页的 `pageParam`:
+
+```tsx
+useInfiniteQuery({
+ queryKey,
+- queryFn: ({ pageParam = 0 }) => fetchSomething(pageParam), // [!code --]
++ queryFn: ({ pageParam }) => fetchSomething(pageParam), // [!code ++]
++ initialPageParam: 0, // [!code ++]
+ getNextPageParam: (lastPage) => lastPage.next,
+})
+```
+
+### 移除了无限查询的手动模式
+
+此前,我们允许通过直接向 `fetchNextPage` 或 `fetchPreviousPage` 传递 `pageParam` 值来覆盖从 `getNextPageParam` 或 `getPreviousPageParam` 返回的 `pageParams`。此功能在重新获取时完全无效,且不广为人知或使用。这也意味着无限查询现在必须定义 `getNextPageParam`。
+
+### 从 `getNextPageParam` 或 `getPreviousPageParam` 返回 `null` 现在表示没有更多可用页面
+
+在 v4 中,需要显式返回 `undefined` 表示没有更多可用页面。我们扩展了此检查以包括 `null
diff --git a/docs/zh-hans/framework/react/guides/mutations.md b/docs/zh-hans/framework/react/guides/mutations.md
new file mode 100644
index 00000000000..9b464085c90
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/mutations.md
@@ -0,0 +1,414 @@
+---
+source-updated-at: '2025-03-18T08:45:11.000Z'
+translation-updated-at: '2025-05-06T04:14:31.297Z'
+id: mutations
+title: 变更
+---
+
+与查询不同,变更 (mutations) 通常用于创建/更新/删除数据或执行服务端副作用。为此,TanStack Query 导出了 `useMutation` 钩子。
+
+以下是一个向服务器添加新待办事项的变更示例:
+
+[//]: # 'Example'
+
+```tsx
+function App() {
+ const mutation = useMutation({
+ mutationFn: (newTodo) => {
+ return axios.post('/todos', newTodo)
+ },
+ })
+
+ return (
+
+ {mutation.isPending ? (
+ '添加待办中...'
+ ) : (
+ <>
+ {mutation.isError ? (
+
发生错误:{mutation.error.message}
+ ) : null}
+
+ {mutation.isSuccess ?
待办事项已添加!
: null}
+
+
{
+ mutation.mutate({ id: new Date(), title: '洗衣服' })
+ }}
+ >
+ 创建待办事项
+
+ >
+ )}
+
+ )
+}
+```
+
+[//]: # 'Example'
+
+变更在任何时刻只能处于以下状态之一:
+
+- `isIdle` 或 `status === 'idle'` - 变更当前处于空闲或重置状态
+- `isPending` 或 `status === 'pending'` - 变更正在执行中
+- `isError` 或 `status === 'error'` - 变更遇到错误
+- `isSuccess` 或 `status === 'success'` - 变更成功完成且数据可用
+
+除了这些主要状态外,根据变更状态还可获取更多信息:
+
+- `error` - 如果变更处于 `error` 状态,可通过 `error` 属性获取错误信息。
+- `data` - 如果变更处于 `success` 状态,可通过 `data` 属性获取数据。
+
+在上面的示例中,您还看到可以通过调用 `mutate` 函数并传递**单个变量或对象**来向变更函数传递变量。
+
+仅使用变量时,变更并不特殊,但当与 `onSuccess` 选项、[Query Client 的 `invalidateQueries` 方法](../../../reference/QueryClient.md#queryclientinvalidatequeries) 和 [Query Client 的 `setQueryData` 方法](../../../reference/QueryClient.md#queryclientsetquerydata) 结合使用时,变更将成为非常强大的工具。
+
+[//]: # 'Info1'
+
+> 重要提示:`mutate` 函数是一个异步函数,这意味着在 **React 16 及更早版本** 中不能直接在事件回调中使用它。如果需要在 `onSubmit` 中访问事件,必须将 `mutate` 包装在另一个函数中。这是由于 [React 事件池机制](https://reactjs.org/docs/legacy-event-pooling.html)。
+
+[//]: # 'Info1'
+[//]: # 'Example2'
+
+```tsx
+// 在 React 16 及更早版本中,以下代码无法工作
+const CreateTodo = () => {
+ const mutation = useMutation({
+ mutationFn: (event) => {
+ event.preventDefault()
+ return fetch('/api', new FormData(event.target))
+ },
+ })
+
+ return
+}
+
+// 以下代码可以正常工作
+const CreateTodo = () => {
+ const mutation = useMutation({
+ mutationFn: (formData) => {
+ return fetch('/api', formData)
+ },
+ })
+ const onSubmit = (event) => {
+ event.preventDefault()
+ mutation.mutate(new FormData(event.target))
+ }
+
+ return
+}
+```
+
+[//]: # 'Example2'
+
+## 重置变更状态
+
+有时需要清除变更请求的 `error` 或 `data`。为此,可以使用 `reset` 函数来处理:
+
+[//]: # 'Example3'
+
+```tsx
+const CreateTodo = () => {
+ const [title, setTitle] = useState('')
+ const mutation = useMutation({ mutationFn: createTodo })
+
+ const onCreateTodo = (e) => {
+ e.preventDefault()
+ mutation.mutate({ title })
+ }
+
+ return (
+
+ )
+}
+```
+
+[//]: # 'Example3'
+
+## 变更副作用
+
+`useMutation` 提供了一些辅助选项,允许在变更生命周期的任何阶段快速简单地执行副作用。这些选项对于[变更后使查询失效并重新获取](./invalidations-from-mutations.md) 甚至[乐观更新](./optimistic-updates.md) 非常有用。
+
+[//]: # 'Example4'
+
+```tsx
+useMutation({
+ mutationFn: addTodo,
+ onMutate: (variables) => {
+ // 变更即将执行!
+ // 可选返回一个包含数据的上下文,用于例如回滚操作
+ return { id: 1 }
+ },
+ onError: (error, variables, context) => {
+ // 发生错误!
+ console.log(`回滚乐观更新,ID:${context.id}`)
+ },
+ onSuccess: (data, variables, context) => {
+ // 成功!
+ },
+ onSettled: (data, error, variables, context) => {
+ // 无论错误还是成功都会执行!
+ },
+})
+```
+
+[//]: # 'Example4'
+
+在任何回调函数中返回 Promise 时,会先等待该 Promise 完成再调用下一个回调:
+
+[//]: # 'Example5'
+
+```tsx
+useMutation({
+ mutationFn: addTodo,
+ onSuccess: async () => {
+ console.log('我是第一个!')
+ },
+ onSettled: async () => {
+ console.log('我是第二个!')
+ },
+})
+```
+
+[//]: # 'Example5'
+
+您可能希望在调用 `mutate` 时**触发额外的回调**,而不仅限于 `useMutation` 中定义的回调。这可用于触发组件特定的副作用。为此,可以在变更变量之后向 `mutate` 函数提供相同的回调选项。支持的选项包括:`onSuccess`、`onError` 和 `onSettled`。请注意,如果组件在变更完成前卸载,这些额外的回调将不会执行。
+
+[//]: # 'Example6'
+
+```tsx
+useMutation({
+ mutationFn: addTodo,
+ onSuccess: (data, variables, context) => {
+ // 我会先触发
+ },
+ onError: (error, variables, context) => {
+ // 我会先触发
+ },
+ onSettled: (data, error, variables, context) => {
+ // 我会先触发
+ },
+})
+
+mutate(todo, {
+ onSuccess: (data, variables, context) => {
+ // 我会第二个触发!
+ },
+ onError: (error, variables, context) => {
+ // 我会第二个触发!
+ },
+ onSettled: (data, error, variables, context) => {
+ // 我会第二个触发!
+ },
+})
+```
+
+[//]: # 'Example6'
+
+### 连续变更
+
+在处理连续变更时,`onSuccess`、`onError` 和 `onSettled` 回调的行为略有不同。当传递给 `mutate` 函数时,它们只会触发一次,并且仅在组件仍挂载时触发。这是因为每次调用 `mutate` 函数时,变更观察器会被移除并重新订阅。相反,`useMutation` 的处理程序会为每次 `mutate` 调用执行。
+
+> 请注意,传递给 `useMutation` 的 `mutationFn` 很可能是异步的。在这种情况下,变更完成的顺序可能与 `mutate` 函数调用的顺序不同。
+
+[//]: # 'Example7'
+
+```tsx
+useMutation({
+ mutationFn: addTodo,
+ onSuccess: (data, variables, context) => {
+ // 会被调用 3 次
+ },
+})
+
+const todos = ['待办 1', '待办 2', '待办 3']
+todos.forEach((todo) => {
+ mutate(todo, {
+ onSuccess: (data, variables, context) => {
+ // 只会执行一次,针对最后一次变更(待办 3),
+ // 无论哪次变更先完成
+ },
+ })
+})
+```
+
+[//]: # 'Example7'
+
+## Promise
+
+使用 `mutateAsync` 替代 `mutate` 可以获取一个 Promise,该 Promise 在成功时解析或在出错时抛出异常。例如,这可用于组合副作用。
+
+[//]: # 'Example8'
+
+```tsx
+const mutation = useMutation({ mutationFn: addTodo })
+
+try {
+ const todo = await mutation.mutateAsync(todo)
+ console.log(todo)
+} catch (error) {
+ console.error(error)
+} finally {
+ console.log('完成')
+}
+```
+
+[//]: # 'Example8'
+
+## 重试
+
+默认情况下,TanStack Query 不会在出错时重试变更,但可以通过 `retry` 选项启用:
+
+[//]: # 'Example9'
+
+```tsx
+const mutation = useMutation({
+ mutationFn: addTodo,
+ retry: 3,
+})
+```
+
+[//]: # 'Example9'
+
+如果因设备离线导致变更失败,它们将在设备重新连接时按相同顺序重试。
+
+## 持久化变更
+
+如果需要,可以将变更持久化到存储中,并在稍后恢复。这可以通过 hydration 函数实现:
+
+[//]: # 'Example10'
+
+```tsx
+const queryClient = new QueryClient()
+
+// 定义 "addTodo" 变更
+queryClient.setMutationDefaults(['addTodo'], {
+ mutationFn: addTodo,
+ onMutate: async (variables) => {
+ // 取消当前待办列表的查询
+ await queryClient.cancelQueries({ queryKey: ['todos'] })
+
+ // 创建乐观待办事项
+ const optimisticTodo = { id: uuid(), title: variables.title }
+
+ // 将乐观待办事项添加到待办列表
+ queryClient.setQueryData(['todos'], (old) => [...old, optimisticTodo])
+
+ // 返回包含乐观待办事项的上下文
+ return { optimisticTodo }
+ },
+ onSuccess: (result, variables, context) => {
+ // 用结果替换待办列表中的乐观待办事项
+ queryClient.setQueryData(['todos'], (old) =>
+ old.map((todo) =>
+ todo.id === context.optimisticTodo.id ? result : todo,
+ ),
+ )
+ },
+ onError: (error, variables, context) => {
+ // 从待办列表中移除乐观待办事项
+ queryClient.setQueryData(['todos'], (old) =>
+ old.filter((todo) => todo.id !== context.optimisticTodo.id),
+ )
+ },
+ retry: 3,
+})
+
+// 在某个组件中启动变更:
+const mutation = useMutation({ mutationKey: ['addTodo'] })
+mutation.mutate({ title: '标题' })
+
+// 如果因设备离线等原因暂停了变更,
+// 可以在应用退出时将暂停的变更脱水:
+const state = dehydrate(queryClient)
+
+// 然后在应用启动时重新水合:
+hydrate(queryClient, state)
+
+// 恢复暂停的变更:
+queryClient.resumePausedMutations()
+```
+
+[//]: # 'Example10'
+
+### 持久化离线变更
+
+如果使用 [persistQueryClient 插件](../plugins/persistQueryClient.md) 持久化离线变更,除非提供默认的变更函数,否则在页面重新加载时无法恢复变更。
+
+这是一个技术限制。当持久化到外部存储时,只有变更的状态会被持久化,因为函数无法序列化。水合后,触发变更的组件可能未挂载,因此调用 `resumePausedMutations` 可能会导致错误:`未找到 mutationFn`。
+
+[//]: # 'Example11'
+
+```tsx
+const persister = createSyncStoragePersister({
+ storage: window.localStorage,
+})
+const queryClient = new QueryClient({
+ defaultOptions: {
+ queries: {
+ gcTime: 1000 * 60 * 60 * 24, // 24 小时
+ },
+ },
+})
+
+// 需要一个默认的变更函数,以便页面重新加载后可以恢复暂停的变更
+queryClient.setMutationDefaults(['todos'], {
+ mutationFn: ({ id, data }) => {
+ return api.updateTodo(id, data)
+ },
+})
+
+export default function App() {
+ return (
+ {
+ // 从 localStorage 初始恢复成功后恢复变更
+ queryClient.resumePausedMutations()
+ }}
+ >
+
+
+ )
+}
+```
+
+[//]: # 'Example11'
+
+我们还提供了一个全面的[离线示例](../examples/react/offline),涵盖了查询和变更。
+
+## 变更作用域
+
+默认情况下,所有变更并行运行——即使多次调用同一变更的 `.mutate()`。可以通过为变更指定带有 `id` 的 `scope` 来避免这种情况。具有相同 `scope.id` 的所有变更将串行运行,这意味着当它们被触发时,如果该作用域已有变更在进行中,它们将以 `isPaused: true` 状态开始。它们会被放入队列,并在轮到它们时自动恢复。
+
+[//]: # 'ExampleScopes'
+
+```tsx
+const mutation = useMutation({
+ mutationFn: addTodo,
+ scope: {
+ id: 'todo',
+ },
+})
+```
+
+[//]: # 'ExampleScopes'
+[//]: # 'Materials'
+
+## 延伸阅读
+
+有关变更的更多信息,请查看社区资源中的 [#12: 掌握 React Query 中的变更](../community/tkdodos-blog.md#12-mastering-mutations-in-react-query)。
+
+[//]: # 'Materials'
diff --git a/docs/zh-hans/framework/react/guides/network-mode.md b/docs/zh-hans/framework/react/guides/network-mode.md
new file mode 100644
index 00000000000..ac58dfba947
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/network-mode.md
@@ -0,0 +1,48 @@
+---
+source-updated-at: '2025-03-18T08:45:11.000Z'
+translation-updated-at: '2025-05-06T04:13:05.806Z'
+id: network-mode
+title: 网络模式
+---
+
+TanStack Query 提供了三种不同的网络模式,用于区分在无网络连接时[查询(Queries)](./queries.md)和[变更(Mutations)](./mutations.md)的行为。该模式可以针对每个查询/变更单独设置,也可以通过查询/变更的全局默认值进行配置。
+
+由于 TanStack Query 最常与数据获取库配合使用,其默认网络模式为[在线模式(online)](#network-mode-online)。
+
+## 网络模式:在线模式(online)
+
+在此模式下,只有存在网络连接时才会触发查询和变更。这是默认模式。如果因无网络连接导致查询请求无法发起,该查询将始终保持当前状态(`pending`、`error`、`success`)。此外,系统会额外暴露一个[获取状态(fetchStatus)](./queries.md#fetchstatus),其可能值为:
+
+- `fetching`:`queryFn` 正在真实执行——请求正在传输中
+- `paused`:查询未执行——将保持`paused`状态直至恢复网络连接
+- `idle`:查询既未在获取数据也未处于暂停状态
+
+为方便使用,系统会根据此状态派生出`isFetching`和`isPaused`标志。
+
+> 需注意:仅检查`pending`状态可能不足以显示加载动画。如果首次挂载查询时无网络连接,查询可能处于`state: 'pending'`但`fetchStatus: 'paused'`状态。
+
+若查询因网络在线而启动,但在获取过程中断网,TanStack Query 也会暂停重试机制。暂停的查询将在恢复网络连接后继续执行。此行为与`refetchOnReconnect`(该模式默认值为`true`)无关,因为这不是"重新获取",而是"继续执行"。若查询期间被[取消(cancelled)](./query-cancellation.md),则不会继续。
+
+## 网络模式:始终模式(always)
+
+在此模式下,TanStack Query 会忽略在线/离线状态始终执行获取。如果您在不需要活跃网络连接的环境中(例如仅从`AsyncStorage`读取数据,或`queryFn`直接返回`Promise.resolve(5)`)使用 TanStack Query,此模式是理想选择。
+
+- 查询永远不会因断网进入`paused`状态
+- 重试也不会暂停——查询失败后将直接进入`error`状态
+- 此模式下`refetchOnReconnect`默认为`false`,因为网络重连不再意味着需要重新获取过期查询。您仍可手动开启该选项
+
+## 网络模式:离线优先模式(offlineFirst)
+
+此模式是前两种模式的折中方案,TanStack Query 会执行一次`queryFn`,但暂停后续重试。这对于使用[Service Worker拦截请求实现缓存](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Offline_Service_workers)的[离线优先PWA](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Offline_Service_workers),或通过[Cache-Control头](https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching#the_cache-control_header)实现HTTP缓存的场景非常实用。
+
+在这些场景中,首次获取可能因离线存储/缓存而成功。若缓存未命中,网络请求将发出并失败,此时该模式的行为与`online`查询相同——暂停重试。
+
+## 开发者工具(Devtools)
+
+[TanStack Query开发者工具](../devtools.md)会显示处于`paused`状态的查询——这些查询本应获取数据但因断网而暂停。工具还提供*模拟离线行为*的切换按钮。请注意该按钮不会实际干扰网络连接(您可在浏览器开发者工具中操作),而是会将[OnlineManager](../../../reference/onlineManager.md)设置为离线状态。
+
+## 函数签名(Signature)
+
+- `networkMode: 'online' | 'always' | 'offlineFirst'`
+ - 可选参数
+ - 默认值:`'online'`
diff --git a/docs/zh-hans/framework/react/guides/optimistic-updates.md b/docs/zh-hans/framework/react/guides/optimistic-updates.md
new file mode 100644
index 00000000000..2581b5a524b
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/optimistic-updates.md
@@ -0,0 +1,188 @@
+---
+source-updated-at: '2025-03-26T09:27:36.000Z'
+translation-updated-at: '2025-05-06T04:12:25.239Z'
+id: optimistic-updates
+title: 乐观更新
+---
+
+React Query 提供了两种在变更操作完成前乐观更新 UI 的方式。你可以直接使用 `onMutate` 选项更新缓存,或者利用 `useMutation` 返回的 `variables` 来更新 UI。
+
+## 通过 UI 更新
+
+这是更简单的实现方式,因为它不直接与缓存交互。
+
+[//]: # 'ExampleUI1'
+
+```tsx
+const addTodoMutation = useMutation({
+ mutationFn: (newTodo: string) => axios.post('/api/data', { text: newTodo }),
+ // 确保返回查询失效的 Promise
+ // 这样变更会保持 `pending` 状态直到重新获取完成
+ onSettled: () => queryClient.invalidateQueries({ queryKey: ['todos'] }),
+})
+
+const { isPending, submittedAt, variables, mutate, isError } = addTodoMutation
+```
+
+[//]: # 'ExampleUI1'
+
+之后你可以访问 `addTodoMutation.variables` 获取新增的待办事项。在渲染查询结果的 UI 列表中,当变更处于 `isPending` 状态时,可以临时添加一项:
+
+[//]: # 'ExampleUI2'
+
+```tsx
+
+ {todoQuery.items.map((todo) => (
+ {todo.text}
+ ))}
+ {isPending && {variables} }
+
+```
+
+[//]: # 'ExampleUI2'
+
+我们通过不同的 `opacity` 样式渲染临时项,直到变更完成。成功后该项会自动消失。如果重新获取成功,列表中会显示为正常项。
+
+若变更失败,该项同样会消失。但如需保留显示,可以通过检查变更的 `isError` 状态实现。出错时 `variables` 不会被清除,因此仍可访问,甚至显示重试按钮:
+
+[//]: # 'ExampleUI3'
+
+```tsx
+{
+ isError && (
+
+ {variables}
+ mutate(variables)}>重试
+
+ )
+}
+```
+
+[//]: # 'ExampleUI3'
+
+### 当变更与查询不在同一组件时
+
+若变更与查询位于同一组件,此方案效果良好。但通过专用的 `useMutationState` 钩子,你也能在其他组件访问所有变更。最佳实践是配合 `mutationKey` 使用:
+
+[//]: # 'ExampleUI4'
+
+```tsx
+// 应用某处
+const { mutate } = useMutation({
+ mutationFn: (newTodo: string) => axios.post('/api/data', { text: newTodo }),
+ onSettled: () => queryClient.invalidateQueries({ queryKey: ['todos'] }),
+ mutationKey: ['addTodo'],
+})
+
+// 在其他位置访问 variables
+const variables = useMutationState({
+ filters: { mutationKey: ['addTodo'], status: 'pending' },
+ select: (mutation) => mutation.state.variables,
+})
+```
+
+[//]: # 'ExampleUI4'
+
+`variables` 会是 `Array` 类型,因为可能同时存在多个进行中的变更。如需为项生成唯一键,还可选择 `mutation.state.submittedAt`。这让处理并发的乐观更新变得轻松。
+
+## 通过缓存更新
+
+在变更前乐观更新状态时,存在操作失败的可能。多数情况下只需重新获取乐观查询即可恢复至真实服务端状态。但某些场景下重新获取可能失效,此时需手动回滚更新。
+
+为此,`useMutation` 的 `onMutate` 处理程序允许返回一个值,该值将作为末参数传递给 `onError` 和 `onSettled` 处理程序。通常传递回滚函数最为实用。
+
+### 新增待办事项时更新列表
+
+[//]: # 'Example'
+
+```tsx
+const queryClient = useQueryClient()
+
+useMutation({
+ mutationFn: updateTodo,
+ // 当 mutate 调用时:
+ onMutate: async (newTodo) => {
+ // 取消所有进行中的重新获取
+ // (避免覆盖我们的乐观更新)
+ await queryClient.cancelQueries({ queryKey: ['todos'] })
+
+ // 保存当前值的快照
+ const previousTodos = queryClient.getQueryData(['todos'])
+
+ // 乐观更新至新值
+ queryClient.setQueryData(['todos'], (old) => [...old, newTodo])
+
+ // 返回包含快照值的上下文对象
+ return { previousTodos }
+ },
+ // 若变更失败
+ // 使用 onMutate 返回的上下文回滚
+ onError: (err, newTodo, context) => {
+ queryClient.setQueryData(['todos'], context.previousTodos)
+ },
+ // 无论成功失败都重新获取:
+ onSettled: () => queryClient.invalidateQueries({ queryKey: ['todos'] }),
+})
+```
+
+[//]: # 'Example'
+
+### 更新单个待办事项
+
+[//]: # 'Example2'
+
+```tsx
+useMutation({
+ mutationFn: updateTodo,
+ // 当 mutate 调用时:
+ onMutate: async (newTodo) => {
+ // 取消相关重新获取
+ await queryClient.cancelQueries({ queryKey: ['todos', newTodo.id] })
+
+ // 保存旧值快照
+ const previousTodo = queryClient.getQueryData(['todos', newTodo.id])
+
+ // 乐观更新
+ queryClient.setQueryData(['todos', newTodo.id], newTodo)
+
+ // 返回包含新旧值的上下文
+ return { previousTodo, newTodo }
+ },
+ // 失败时使用上方返回的上下文
+ onError: (err, newTodo, context) => {
+ queryClient.setQueryData(
+ ['todos', context.newTodo.id],
+ context.previousTodo,
+ )
+ },
+ // 总是重新获取:
+ onSettled: (newTodo) =>
+ queryClient.invalidateQueries({ queryKey: ['todos', newTodo.id] }),
+})
+```
+
+[//]: # 'Example2'
+
+也可用 `onSettled` 替代单独的 `onError` 和 `onSuccess` 处理程序:
+
+[//]: # 'Example3'
+
+```tsx
+useMutation({
+ mutationFn: updateTodo,
+ // ...
+ onSettled: async (newTodo, error, variables, context) => {
+ if (error) {
+ // 错误处理
+ }
+ },
+})
+```
+
+[//]: # 'Example3'
+
+## 方案选择建议
+
+若只需在单一位置显示乐观结果,使用 `variables` 直接更新 UI 的方案代码更少且更易理解。例如完全无需处理回滚。
+
+但若界面有多个位置需要感知更新,直接操作缓存会自动同步所有相关位置。
diff --git a/docs/zh-hans/framework/react/guides/paginated-queries.md b/docs/zh-hans/framework/react/guides/paginated-queries.md
new file mode 100644
index 00000000000..a74ce04546f
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/paginated-queries.md
@@ -0,0 +1,95 @@
+---
+source-updated-at: '2024-07-18T12:50:17.000Z'
+translation-updated-at: '2025-05-06T04:09:51.300Z'
+id: paginated-queries
+title: 分页查询
+---
+
+分页数据的渲染是一种非常常见的 UI 模式,在 TanStack Query 中,只需将页码信息包含在查询键 (query key) 中即可"开箱即用":
+
+[//]: # 'Example'
+
+```tsx
+const result = useQuery({
+ queryKey: ['projects', page],
+ queryFn: fetchProjects,
+})
+```
+
+[//]: # 'Example'
+
+然而,如果你运行这个简单示例,可能会注意到一个奇怪的现象:
+
+**UI 会在 `success` 和 `pending` 状态之间不断切换,因为每个新页面都被视为一个全新的查询。**
+
+这种体验并不理想,但不幸的是,这正是当今许多工具的工作方式。但 TanStack Query 不同!你可能已经猜到了,TanStack Query 提供了一个名为 `placeholderData` 的强大功能来解决这个问题。
+
+## 使用 `placeholderData` 实现更好的分页查询
+
+考虑以下示例,我们理想情况下希望递增查询的页码 (pageIndex) 或游标 (cursor)。如果使用 `useQuery`,**技术上仍然可以正常工作**,但随着为每个页面创建和销毁不同的查询,UI 会在 `success` 和 `pending` 状态之间跳跃。通过将 `placeholderData` 设置为 `(previousData) => previousData` 或使用 TanStack Query 导出的 `keepPreviousData` 函数,我们可以获得以下改进:
+
+- **即使查询键发生了变化,在请求新数据时,上次成功获取的数据仍然可用**
+- 当新数据到达时,之前的 `data` 会无缝切换以显示新数据
+- 可以通过 `isPlaceholderData` 判断当前查询提供的是哪类数据
+
+[//]: # 'Example2'
+
+```tsx
+import { keepPreviousData, useQuery } from '@tanstack/react-query'
+import React from 'react'
+
+function Todos() {
+ const [page, setPage] = React.useState(0)
+
+ const fetchProjects = (page = 0) =>
+ fetch('/api/projects?page=' + page).then((res) => res.json())
+
+ const { isPending, isError, error, data, isFetching, isPlaceholderData } =
+ useQuery({
+ queryKey: ['projects', page],
+ queryFn: () => fetchProjects(page),
+ placeholderData: keepPreviousData,
+ })
+
+ return (
+
+ {isPending ? (
+
Loading...
+ ) : isError ? (
+
Error: {error.message}
+ ) : (
+
+ {data.projects.map((project) => (
+
{project.name}
+ ))}
+
+ )}
+
Current Page: {page + 1}
+
setPage((old) => Math.max(old - 1, 0))}
+ disabled={page === 0}
+ >
+ Previous Page
+
+
{
+ if (!isPlaceholderData && data.hasMore) {
+ setPage((old) => old + 1)
+ }
+ }}
+ // Disable the Next Page button until we know a next page is available
+ disabled={isPlaceholderData || !data?.hasMore}
+ >
+ Next Page
+
+ {isFetching ?
Loading... : null}
+
+ )
+}
+```
+
+[//]: # 'Example2'
+
+## 使用 `placeholderData` 延迟无限查询结果
+
+虽然不太常见,但 `placeholderData` 选项与 `useInfiniteQuery` 钩子也能完美配合,因此你可以让用户在无限查询键随时间变化时,仍然无缝查看缓存数据。
diff --git a/docs/zh-hans/framework/react/guides/parallel-queries.md b/docs/zh-hans/framework/react/guides/parallel-queries.md
new file mode 100644
index 00000000000..f75c9fa138c
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/parallel-queries.md
@@ -0,0 +1,58 @@
+---
+source-updated-at: '2024-01-25T20:57:22.000Z'
+translation-updated-at: '2025-05-06T04:09:37.356Z'
+id: parallel-queries
+title: 并行查询
+---
+
+"并行 (Parallel)" 查询是指同时执行多个查询,以最大化数据获取的并发性。
+
+## 手动并行查询
+
+当并行查询的数量固定不变时,使用并行查询**无需额外操作**。只需并列使用任意数量的 TanStack Query 提供的 `useQuery` 和 `useInfiniteQuery` 钩子即可!
+
+[//]: # '示例'
+
+```tsx
+function App () {
+ // 以下查询将并行执行
+ const usersQuery = useQuery({ queryKey: ['users'], queryFn: fetchUsers })
+ const teamsQuery = useQuery({ queryKey: ['teams'], queryFn: fetchTeams })
+ const projectsQuery = useQuery({ queryKey: ['projects'], queryFn: fetchProjects })
+ ...
+}
+```
+
+[//]: # '示例'
+[//]: # '提示'
+
+> 在 suspense 模式下使用 React Query 时,这种并行模式会失效,因为第一个查询会在内部抛出 promise 并挂起组件,导致其他查询无法执行。解决方案是使用 `useSuspenseQueries` 钩子(推荐方式),或通过为每个 `useSuspenseQuery` 实例创建独立组件来实现并行控制。
+
+[//]: # '提示'
+
+## 使用 `useQueries` 实现动态并行查询
+
+[//]: # '动态并行介绍'
+
+如果需要在每次渲染时动态调整查询数量,手动查询的方式会违反钩子规则。此时应使用 TanStack Query 提供的 `useQueries` 钩子,它可以动态执行任意数量的并行查询。
+
+[//]: # '动态并行介绍'
+
+`useQueries` 接收一个包含 **queries 键**的**配置对象**,其值为**查询对象数组**。该钩子返回一个**查询结果数组**:
+
+[//]: # '示例2'
+
+```tsx
+function App({ users }) {
+ const userQueries = useQueries({
+ queries: users.map((user) => {
+ return {
+ queryKey: ['user', user.id],
+ queryFn: () => fetchUserById(user.id),
+ }
+ }),
+ })
+}
+```
+
+[//]: # '示例2'
diff --git a/docs/zh-hans/framework/react/guides/placeholder-query-data.md b/docs/zh-hans/framework/react/guides/placeholder-query-data.md
new file mode 100644
index 00000000000..b90b647c2fd
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/placeholder-query-data.md
@@ -0,0 +1,103 @@
+---
+source-updated-at: '2025-03-18T08:45:11.000Z'
+translation-updated-at: '2025-05-06T04:09:43.190Z'
+id: placeholder-query-data
+title: 占位查询数据
+---
+
+## 什么是占位数据 (Placeholder Data)?
+
+占位数据允许查询表现得好像已经拥有数据,类似于 `initialData` 选项,但**这些数据不会被持久化到缓存中**。这在以下场景中非常有用:当实际数据还在后台获取时,你已经拥有部分(或模拟)数据可以成功渲染查询结果。
+
+> 示例:一篇博客文章的查询可以从父级博客列表获取仅包含标题和正文片段缩略的“预览”数据。你可能不希望将这些部分数据持久化到独立查询的结果中,但它对于尽快展示内容布局非常有用,同时实际查询会继续获取完整数据。
+
+有几种方式可以在需要之前为查询提供占位数据:
+
+- 声明式:
+ - 为查询提供 `placeholderData`,以便在缓存为空时预填充数据
+- 命令式:
+ - [使用 `queryClient` 和 `placeholderData` 选项预取或获取数据](./prefetching.md)
+
+当我们使用 `placeholderData` 时,查询不会处于 `pending` 状态——它会直接从 `success` 状态开始,因为我们有可以显示的 `data`,即使这些数据只是“占位”数据。为了将其与“真实”数据区分开,查询结果中还会将 `isPlaceholderData` 标志设为 `true`。
+
+## 作为值的占位数据
+
+[//]: # 'ExampleValue'
+
+```tsx
+function Todos() {
+ const result = useQuery({
+ queryKey: ['todos'],
+ queryFn: () => fetch('/todos'),
+ placeholderData: placeholderTodos,
+ })
+}
+```
+
+[//]: # 'ExampleValue'
+[//]: # 'Memoization'
+
+### 占位数据记忆化 (Memoization)
+
+如果获取查询占位数据的过程计算密集,或者你不想在每次渲染时都执行,可以对值进行记忆化处理:
+
+```tsx
+function Todos() {
+ const placeholderData = useMemo(() => generateFakeTodos(), [])
+ const result = useQuery({
+ queryKey: ['todos'],
+ queryFn: () => fetch('/todos'),
+ placeholderData,
+ })
+}
+```
+
+[//]: # 'Memoization'
+
+## 作为函数的占位数据
+
+`placeholderData` 也可以是一个函数,通过它你可以访问“先前”成功查询的数据和查询元信息。这在你想用一个查询的数据作为另一个查询的占位数据时非常有用。当查询键 (QueryKey) 发生变化时(例如从 `['todos', 1]` 变为 `['todos', 2]`),我们可以继续显示“旧”数据,而不是在数据从一个查询过渡到另一个查询时显示加载状态。更多信息请参阅[分页查询](./paginated-queries.md)。
+
+[//]: # 'ExampleFunction'
+
+```tsx
+const result = useQuery({
+ queryKey: ['todos', id],
+ queryFn: () => fetch(`/todos/${id}`),
+ placeholderData: (previousData, previousQuery) => previousData,
+})
+```
+
+[//]: # 'ExampleFunction'
+
+### 从缓存获取占位数据
+
+在某些情况下,你可以从另一个查询的缓存结果中获取占位数据。一个典型的例子是从博客文章列表查询的缓存数据中搜索文章的预览版本,然后将其用作独立文章查询的占位数据:
+
+[//]: # 'ExampleCache'
+
+```tsx
+function Todo({ blogPostId }) {
+ const queryClient = useQueryClient()
+ const result = useQuery({
+ queryKey: ['blogPost', blogPostId],
+ queryFn: () => fetch(`/blogPosts/${blogPostId}`),
+ placeholderData: () => {
+ // 使用 'blogPosts' 查询中的小型/预览版博客文章数据
+ // 作为当前博客文章查询的占位数据
+ return queryClient
+ .getQueryData(['blogPosts'])
+ ?.find((d) => d.id === blogPostId)
+ },
+ })
+}
+```
+
+[//]: # 'ExampleCache'
+[//]: # 'Materials'
+
+## 扩展阅读
+
+要比较 `占位数据 (Placeholder Data)` 和 `初始数据 (Initial Data)` 的区别,请查看[社区资源](../community/tkdodos-blog.md#9-placeholder-and-initial-data-in-react-query)。
+
+[//]: # 'Materials'
diff --git a/docs/zh-hans/framework/react/guides/prefetching.md b/docs/zh-hans/framework/react/guides/prefetching.md
new file mode 100644
index 00000000000..9af3111b678
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/prefetching.md
@@ -0,0 +1,437 @@
+---
+source-updated-at: '2025-03-18T08:45:11.000Z'
+translation-updated-at: '2025-05-06T04:11:22.321Z'
+id: prefetching
+title: 预获取与路由集成
+---
+
+当您预知或推测某块数据即将被需要时,可以通过预取 (prefetching) 提前将该数据填充到缓存中,从而获得更快的用户体验。
+
+预取存在几种不同的实现模式:
+
+1. 在事件处理器中预取
+2. 在组件中预取
+3. 通过路由集成预取
+4. 在服务端渲染时预取(路由集成的另一种形式)
+
+本指南将探讨前三种模式,而第四种模式将在[《服务端渲染与注水指南》](./ssr.md)和[《高级服务端渲染指南》](./advanced-ssr.md)中深入讲解。
+
+预取的一个典型应用场景是避免请求瀑布流 (Request Waterfalls),相关背景和原理详见[《性能与请求瀑布流指南》](./request-waterfalls.md)。
+
+## prefetchQuery 与 prefetchInfiniteQuery
+
+在深入具体预取模式前,我们先了解 `prefetchQuery` 和 `prefetchInfiniteQuery` 函数的基础特性:
+
+- 默认情况下,这些函数会使用 `queryClient` 配置的默认 `staleTime` 来判断缓存中的现有数据是否新鲜或需要重新获取
+- 也可指定自定义的 `staleTime`:`prefetchQuery({ queryKey: ['todos'], queryFn: fn, staleTime: 5000 })`
+ - 此 `staleTime` 仅作用于预取操作,仍需为 `useQuery` 调用单独设置
+ - 若需忽略 `staleTime` 直接返回缓存中的可用数据,可使用 `ensureQueryData` 函数
+ - 提示:在服务端预取时,建议为 `queryClient` 设置高于 `0` 的默认 `staleTime`,避免为每个预取调用单独传参
+- 如果预取的查询没有对应的 `useQuery` 实例,将在 `gcTime` 指定时间后被删除并进行垃圾回收
+- 这些函数返回 `Promise` 且不返回查询数据。如需获取数据,请改用 `fetchQuery`/`fetchInfiniteQuery`
+- 预取函数不会抛出错误,因为它们通常会在 `useQuery` 中重试请求作为优雅降级方案。如需错误捕获,请改用 `fetchQuery`/`fetchInfiniteQuery`
+
+`prefetchQuery` 的使用示例如下:
+
+[//]: # 'ExamplePrefetchQuery'
+
+```tsx
+const prefetchTodos = async () => {
+ // 该查询结果会像普通查询一样被缓存
+ await queryClient.prefetchQuery({
+ queryKey: ['todos'],
+ queryFn: fetchTodos,
+ })
+}
+```
+
+[//]: # 'ExamplePrefetchQuery'
+
+无限查询 (Infinite Queries) 的预取方式与常规查询相同。默认仅预取第一页数据并存储于指定 QueryKey 下。如需预取多页数据,可使用 `pages` 选项并配合 `getNextPageParam` 函数:
+
+[//]: # 'ExamplePrefetchInfiniteQuery'
+
+```tsx
+const prefetchProjects = async () => {
+ // 该查询结果会像普通查询一样被缓存
+ await queryClient.prefetchInfiniteQuery({
+ queryKey: ['projects'],
+ queryFn: fetchProjects,
+ initialPageParam: 0,
+ getNextPageParam: (lastPage, pages) => lastPage.nextCursor,
+ pages: 3, // 预取前 3 页数据
+ })
+}
+```
+
+[//]: # 'ExamplePrefetchInfiniteQuery'
+
+接下来我们将探讨如何在不同场景下应用这些预取方法。
+
+## 在事件处理器中预取
+
+最直接的预取方式是在用户交互时触发。以下示例通过 `onMouseEnter` 或 `onFocus` 事件调用 `queryClient.prefetchQuery`:
+
+[//]: # 'ExampleEventHandler'
+
+```tsx
+function ShowDetailsButton() {
+ const queryClient = useQueryClient()
+
+ const prefetch = () => {
+ queryClient.prefetchQuery({
+ queryKey: ['details'],
+ queryFn: getDetailsData,
+ // 预取仅在数据早于 staleTime 时触发
+ // 此类场景务必设置该参数
+ staleTime: 60000,
+ })
+ }
+
+ return (
+
+ 查看详情
+
+ )
+}
+```
+
+[//]: # 'ExampleEventHandler'
+
+## 在组件中预取
+
+当预知子组件需要某块数据但需等待其他查询完成时,组件生命周期内的预取非常有用。以下示例来自请求瀑布流指南:
+
+[//]: # 'ExampleComponent'
+
+```tsx
+function Article({ id }) {
+ const { data: articleData, isPending } = useQuery({
+ queryKey: ['article', id],
+ queryFn: getArticleById,
+ })
+
+ if (isPending) {
+ return '文章加载中...'
+ }
+
+ return (
+ <>
+
+
+
+ >
+ )
+}
+
+function Comments({ id }) {
+ const { data, isPending } = useQuery({
+ queryKey: ['article-comments', id],
+ queryFn: getArticleCommentsById,
+ })
+
+ ...
+}
+```
+
+[//]: # 'ExampleComponent'
+
+此时会产生如下请求瀑布流:
+
+```
+1. |> getArticleById()
+2. |> getArticleCommentsById()
+```
+
+如指南所述,优化方案之一是将 `getArticleCommentsById` 查询提升到父组件并通过 props 传递。但当组件层级复杂或关联性较弱时,可以采用预取方案:
+
+[//]: # 'ExampleParentComponent'
+
+```tsx
+function Article({ id }) {
+ const { data: articleData, isPending } = useQuery({
+ queryKey: ['article', id],
+ queryFn: getArticleById,
+ })
+
+ // 预取操作
+ useQuery({
+ queryKey: ['article-comments', id],
+ queryFn: getArticleCommentsById,
+ // 可选优化:避免查询变化导致的重复渲染
+ notifyOnChangeProps: [],
+ })
+
+ if (isPending) {
+ return '文章加载中...'
+ }
+
+ return (
+ <>
+
+
+
+ >
+ )
+}
+
+function Comments({ id }) {
+ const { data, isPending } = useQuery({
+ queryKey: ['article-comments', id],
+ queryFn: getArticleCommentsById,
+ })
+
+ ...
+}
+```
+
+[//]: # 'ExampleParentComponent'
+
+此时请求变为并行:
+
+```
+1. |> getArticleById()
+1. |> getArticleCommentsById()
+```
+
+[//]: # 'Suspense'
+
+若需结合 Suspense 使用预取,需采用特殊处理。由于 `useSuspenseQueries` 会阻塞渲染,而 `useQuery` 又会在 suspenseful query 解析后才启动预取,此时应使用 [`usePrefetchQuery`](../reference/usePrefetchQuery.md) 或 [`usePrefetchInfiniteQuery`](../reference/usePrefetchInfiniteQuery.md) 钩子。
+
+实际需要数据的组件可使用 `useSuspenseQuery`。建议为次级查询包裹单独的 `` 边界,避免阻塞主要数据渲染:
+
+```tsx
+function ArticleLayout({ id }) {
+ usePrefetchQuery({
+ queryKey: ['article-comments', id],
+ queryFn: getArticleCommentsById,
+ })
+
+ return (
+
+
+
+ )
+}
+
+function Article({ id }) {
+ const { data: articleData, isPending } = useSuspenseQuery({
+ queryKey: ['article', id],
+ queryFn: getArticleById,
+ })
+
+ ...
+}
+```
+
+另一种方案是在查询函数内预取,适用于文章与评论数据强关联的场景:
+
+```tsx
+const queryClient = useQueryClient()
+const { data: articleData, isPending } = useQuery({
+ queryKey: ['article', id],
+ queryFn: (...args) => {
+ queryClient.prefetchQuery({
+ queryKey: ['article-comments', id],
+ queryFn: getArticleCommentsById,
+ })
+
+ return getArticleById(...args)
+ },
+})
+```
+
+Effect 中的预取也可行,但注意若同一组件使用 `useSuspenseQuery`,effect 会在查询完成后才执行:
+
+```tsx
+const queryClient = useQueryClient()
+
+useEffect(() => {
+ queryClient.prefetchQuery({
+ queryKey: ['article-comments', id],
+ queryFn: getArticleCommentsById,
+ })
+}, [queryClient, id])
+```
+
+总结组件内预取的四种方案(根据场景选择):
+
+- 使用 `usePrefetchQuery` 或 `usePrefetchInfiniteQuery` 在 Suspense 边界前预取
+- 使用 `useQuery` 或 `useSuspenseQueries` 并忽略结果
+- 在查询函数内预取
+- 在 effect 中预取
+
+接下来我们看更复杂的案例。
+
+[//]: # 'Suspense'
+
+### 依赖查询与代码分割
+
+有时需要基于其他查询结果条件式预取。以下示例来自[《性能与请求瀑布流指南》](./request-waterfalls.md):
+
+[//]: # 'ExampleConditionally1'
+
+```tsx
+// 动态加载 GraphFeedItem 组件
+// 只有在渲染时才会开始加载
+const GraphFeedItem = React.lazy(() => import('./GraphFeedItem'))
+
+function Feed() {
+ const { data, isPending } = useQuery({
+ queryKey: ['feed'],
+ queryFn: getFeed,
+ })
+
+ if (isPending) {
+ return '加载动态中...'
+ }
+
+ return (
+ <>
+ {data.map((feedItem) => {
+ if (feedItem.type === 'GRAPH') {
+ return
+ }
+
+ return
+ })}
+ >
+ )
+}
+
+// GraphFeedItem.tsx
+function GraphFeedItem({ feedItem }) {
+ const { data, isPending } = useQuery({
+ queryKey: ['graph', feedItem.id],
+ queryFn: getGraphDataById,
+ })
+
+ ...
+}
+```
+
+[//]: # 'ExampleConditionally1'
+
+此时会产生双重请求瀑布:
+
+```
+1. |> getFeed()
+2. |> JS for
+3. |> getGraphDataById()
+```
+
+若无法通过 API 重构让 `getFeed()` 返回 `getGraphDataById()` 数据,虽然无法消除 `getFeed->getGraphDataById` 瀑布流,但通过条件预取可实现代码与数据并行加载(以下示例在查询函数中实现):
+
+[//]: # 'ExampleConditionally2'
+
+```tsx
+function Feed() {
+ const queryClient = useQueryClient()
+ const { data, isPending } = useQuery({
+ queryKey: ['feed'],
+ queryFn: async (...args) => {
+ const feed = await getFeed(...args)
+
+ for (const feedItem of feed) {
+ if (feedItem.type === 'GRAPH') {
+ queryClient.prefetchQuery({
+ queryKey: ['graph', feedItem.id],
+ queryFn: getGraphDataById,
+ })
+ }
+ }
+
+ return feed
+ }
+ })
+
+ ...
+}
+```
+
+[//]: # 'ExampleConditionally2'
+
+此时加载流程变为:
+
+```
+1. |> getFeed()
+2. |> JS for
+2. |> getGraphDataById()
+```
+
+但需权衡的是:`getGraphDataById` 的代码现在会打包到父组件中。若 `GraphFeedItem` 出现频率高,这种优化值得;若非常罕见,则可能不划算。
+
+[//]: # 'Router'
+
+## 路由集成
+
+由于组件树内的数据获取容易引发请求瀑布流,而各种修复方案又会在应用中不断累积,将预取集成到路由层成为颇具吸引力的解决方案。
+
+这种方式需要为每个路由预先声明其组件树所需的数据。传统服务端渲染 (SSR) 应用由于需要在渲染前加载所有数据,长期采用此方案(详见[《服务端渲染与注水指南》](./ssr.md))。
+
+以下以 [Tanstack Router](https://tanstack.com/router) 为例展示客户端方案(省略了大量配置代码,完整示例参见 [Tanstack Router 文档](https://tanstack.com/router/latest/docs)):
+
+路由集成时,可选择阻塞渲染直到数据加载完成,或不等待结果立即开始渲染。也可混合使用——等待关键数据同时预取次要数据。本例中 `/article` 路由会等待文章数据加载,同时预取但不阻塞评论数据:
+
+```tsx
+const queryClient = new QueryClient()
+const routerContext = new RouterContext()
+const rootRoute = routerContext.createRootRoute({
+ component: () => { ... }
+})
+
+const articleRoute = new Route({
+ getParentRoute: () => rootRoute,
+ path: 'article',
+ beforeLoad: () => {
+ return {
+ articleQueryOptions: { queryKey: ['article'], queryFn: fetchArticle },
+ commentsQueryOptions: { queryKey: ['comments'], queryFn: fetchComments },
+ }
+ },
+ loader: async ({
+ context: { queryClient },
+ routeContext: { articleQueryOptions, commentsQueryOptions },
+ }) => {
+ // 立即预取评论但不阻塞
+ queryClient.prefetchQuery(commentsQueryOptions)
+
+ // 阻塞直到文章数据加载完成
+ await queryClient.prefetchQuery(articleQueryOptions)
+ },
+ component: ({ useRouteContext }) => {
+ const { articleQueryOptions, commentsQueryOptions } = useRouteContext()
+ const articleQuery = useQuery(articleQueryOptions)
+ const commentsQuery = useQuery(commentsQueryOptions)
+
+ return (
+ ...
+ )
+ },
+ errorComponent: () => '出错了!',
+})
+```
+
+其他路由器的集成方案也可行,参见 [React Router 示例](../examples/react/react-router)。
+
+[//]: # 'Router'
+
+## 手动初始化查询
+
+如果已同步获取到查询数据,可直接使用 [Query Client 的 `setQueryData` 方法](../../../reference/QueryClient.md#queryclientsetquerydata) 通过键值对添加或更新缓存结果:
+
+[//]: # 'ExampleManualPriming'
+
+```tsx
+queryClient.setQueryData(['todos'], todos)
+```
+
+[//]: # 'ExampleManualPriming'
+[//]: # 'Materials'
+
+## 扩展阅读
+
+- 深度探讨如何预先填充查询缓存,请参阅社区资源中的 [#17: 初始化查询缓存](../community/tkdodos-blog.md#17-seeding-the-query-cache)
+- 服务端路由与框架的集成方案类似客户端方案,但需额外处理服务端到客户端的数据注水,详见[《服务端渲染与注水指南》](./ssr.md)
+
+[//]: # 'Materials'
diff --git a/docs/zh-hans/framework/react/guides/queries.md b/docs/zh-hans/framework/react/guides/queries.md
new file mode 100644
index 00000000000..eb75d1a54b5
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/queries.md
@@ -0,0 +1,147 @@
+---
+source-updated-at: '2025-03-18T08:45:11.000Z'
+translation-updated-at: '2025-05-06T04:09:52.666Z'
+id: queries
+title: 查询
+---
+
+## 查询基础
+
+查询是与**唯一键**绑定的、对异步数据源的声明式依赖。查询可用于任何基于 Promise 的方法(包括 GET 和 POST 方法)从服务器获取数据。如果您的方法会修改服务器上的数据,建议改用[变更](./mutations.md)。
+
+要在组件或自定义钩子中订阅查询,至少需要调用 `useQuery` 钩子并传入:
+
+- **该查询的唯一键**
+- 一个返回 Promise 的函数,该 Promise 会:
+ - 解析数据,或
+ - 抛出错误
+
+[//]: # '示例'
+
+```tsx
+import { useQuery } from '@tanstack/react-query'
+
+function App() {
+ const info = useQuery({ queryKey: ['todos'], queryFn: fetchTodoList })
+}
+```
+
+[//]: # '示例'
+
+您提供的**唯一键**将在内部用于重新获取、缓存和在应用程序中共享查询。
+
+`useQuery` 返回的查询结果包含模板渲染和数据使用所需的所有信息:
+
+[//]: # '示例2'
+
+```tsx
+const result = useQuery({ queryKey: ['todos'], queryFn: fetchTodoList })
+```
+
+[//]: # '示例2'
+
+`result` 对象包含几个非常重要的状态,您需要了解这些状态才能高效工作。查询在任意时刻只能处于以下一种状态:
+
+- `isPending` 或 `status === 'pending'` - 查询尚无数据
+- `isError` 或 `status === 'error'` - 查询遇到错误
+- `isSuccess` 或 `status === 'success'` - 查询成功且数据可用
+
+除了这些主要状态外,根据查询状态还可获取更多信息:
+
+- `error` - 如果查询处于 `isError` 状态,可通过 `error` 属性获取错误信息。
+- `data` - 如果查询处于 `isSuccess` 状态,可通过 `data` 属性获取数据。
+- `isFetching` - 在任何状态下,如果查询正在获取数据(包括后台重新获取),`isFetching` 将为 `true`。
+
+对于**大多数**查询,通常只需检查 `isPending` 状态,然后是 `isError` 状态,最后即可假定数据可用并渲染成功状态:
+
+[//]: # '示例3'
+
+```tsx
+function Todos() {
+ const { isPending, isError, data, error } = useQuery({
+ queryKey: ['todos'],
+ queryFn: fetchTodoList,
+ })
+
+ if (isPending) {
+ return 加载中...
+ }
+
+ if (isError) {
+ return 错误:{error.message}
+ }
+
+ // 此时可以认为 `isSuccess === true`
+ return (
+
+ {data.map((todo) => (
+ {todo.title}
+ ))}
+
+ )
+}
+```
+
+[//]: # '示例3'
+
+如果不喜欢使用布尔值,也可以始终使用 `status` 状态:
+
+[//]: # '示例4'
+
+```tsx
+function Todos() {
+ const { status, data, error } = useQuery({
+ queryKey: ['todos'],
+ queryFn: fetchTodoList,
+ })
+
+ if (status === 'pending') {
+ return 加载中...
+ }
+
+ if (status === 'error') {
+ return 错误:{error.message}
+ }
+
+ // 同样 status === 'success',但 "else" 逻辑也适用
+ return (
+
+ {data.map((todo) => (
+ {todo.title}
+ ))}
+
+ )
+}
+```
+
+[//]: # '示例4'
+
+如果在访问 `data` 之前检查了 `pending` 和 `error`,TypeScript 也会正确缩小 `data` 的类型范围。
+
+### 获取状态 (FetchStatus)
+
+除了 `status` 字段外,您还会获得一个额外的 `fetchStatus` 属性,其可选值包括:
+
+- `fetchStatus === 'fetching'` - 查询正在获取数据。
+- `fetchStatus === 'paused'` - 查询希望获取数据,但被暂停。详情请参阅[网络模式](./network-mode.md)指南。
+- `fetchStatus === 'idle'` - 查询当前未进行任何操作。
+
+### 为何有两种不同状态?
+
+后台重新获取和"过时但重新验证"逻辑使得 `status` 和 `fetchStatus` 的所有组合都可能出现。例如:
+
+- 处于 `success` 状态的查询通常处于 `idle` 获取状态,但如果正在进行后台重新获取,也可能处于 `fetching` 状态。
+- 刚挂载且无数据的查询通常处于 `pending` 状态和 `fetching` 获取状态,但如果无网络连接,也可能处于 `paused` 状态。
+
+因此请记住,查询可能处于 `pending` 状态但并未实际获取数据。经验法则:
+
+- `status` 提供关于 `data` 的信息:是否有数据?
+- `fetchStatus` 提供关于 `queryFn` 的信息:是否正在运行?
+
+[//]: # '材料'
+
+## 延伸阅读
+
+如需了解执行状态检查的替代方法,请参阅[社区资源](../community/tkdodos-blog.md#4-status-checks-in-react-query)。
+
+[//]: # '材料'
diff --git a/docs/zh-hans/framework/react/guides/query-cancellation.md b/docs/zh-hans/framework/react/guides/query-cancellation.md
new file mode 100644
index 00000000000..bb0291bd59d
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/query-cancellation.md
@@ -0,0 +1,195 @@
+---
+source-updated-at: '2025-03-31T09:10:06.000Z'
+translation-updated-at: '2025-05-06T04:09:59.909Z'
+id: query-cancellation
+title: 查询取消
+---
+
+TanStack Query 为每个查询函数提供了一个 [`AbortSignal` 实例](https://developer.mozilla.org/docs/Web/API/AbortSignal)。当查询过期或变为非活跃状态时,该 `signal` 将被中止。这意味着所有查询均可取消,您可以根据需要在查询函数内部响应取消操作。最棒的是,您可以在享受自动取消带来的所有优势的同时,继续使用普通的 async/await 语法。
+
+`AbortController` API 在[大多数运行时环境](https://developer.mozilla.org/docs/Web/API/AbortController#browser_compatibility)中可用,但如果您的运行时环境不支持,则需要提供 polyfill。现有[多种 polyfill 可选](https://www.npmjs.com/search?q=abortcontroller%20polyfill)。
+
+## 默认行为
+
+默认情况下,在 Promise 解析前卸载或不再使用的查询*不会*被取消。这意味着 Promise 解析后,结果数据仍会保留在缓存中。这对于已经开始接收查询但尚未完成就卸载组件的情况非常有用。如果您再次挂载组件且查询尚未被垃圾回收,数据将仍然可用。
+
+但如果消费了 `AbortSignal`,Promise 将被取消(例如中止 fetch 请求),因此查询也必须取消。取消查询将导致其状态*回退*到先前的状态。
+
+## 使用 `fetch`
+
+[//]: # '示例'
+
+```tsx
+const query = useQuery({
+ queryKey: ['todos'],
+ queryFn: async ({ signal }) => {
+ const todosResponse = await fetch('/todos', {
+ // 将 signal 传递给 fetch
+ signal,
+ })
+ const todos = await todosResponse.json()
+
+ const todoDetails = todos.map(async ({ details }) => {
+ const response = await fetch(details, {
+ // 或传递给多个请求
+ signal,
+ })
+ return response.json()
+ })
+
+ return Promise.all(todoDetails)
+ },
+})
+```
+
+[//]: # '示例'
+
+## 使用 `axios` [v0.22.0+](https://github.com/axios/axios/releases/tag/v0.22.0)
+
+[//]: # '示例2'
+
+```tsx
+import axios from 'axios'
+
+const query = useQuery({
+ queryKey: ['todos'],
+ queryFn: ({ signal }) =>
+ axios.get('/todos', {
+ // 将 signal 传递给 `axios`
+ signal,
+ }),
+})
+```
+
+[//]: # '示例2'
+
+### 使用低于 v0.22.0 版本的 `axios`
+
+[//]: # '示例3'
+
+```tsx
+import axios from 'axios'
+
+const query = useQuery({
+ queryKey: ['todos'],
+ queryFn: ({ signal }) => {
+ // 为该请求创建新的 CancelToken 源
+ const CancelToken = axios.CancelToken
+ const source = CancelToken.source()
+
+ const promise = axios.get('/todos', {
+ // 将 source token 传递给请求
+ cancelToken: source.token,
+ })
+
+ // 如果 TanStack Query 发出中止信号,则取消请求
+ signal?.addEventListener('abort', () => {
+ source.cancel('Query was cancelled by TanStack Query')
+ })
+
+ return promise
+ },
+})
+```
+
+[//]: # '示例3'
+
+## 使用 `XMLHttpRequest`
+
+[//]: # '示例4'
+
+```tsx
+const query = useQuery({
+ queryKey: ['todos'],
+ queryFn: ({ signal }) => {
+ return new Promise((resolve, reject) => {
+ var oReq = new XMLHttpRequest()
+ oReq.addEventListener('load', () => {
+ resolve(JSON.parse(oReq.responseText))
+ })
+ signal?.addEventListener('abort', () => {
+ oReq.abort()
+ reject()
+ })
+ oReq.open('GET', '/todos')
+ oReq.send()
+ })
+ },
+})
+```
+
+[//]: # '示例4'
+
+## 使用 `graphql-request`
+
+可以在客户端的 `request` 方法中设置 `AbortSignal`。
+
+[//]: # '示例5'
+
+```tsx
+const client = new GraphQLClient(endpoint)
+
+const query = useQuery({
+ queryKey: ['todos'],
+ queryFn: ({ signal }) => {
+ client.request({ document: query, signal })
+ },
+})
+```
+
+[//]: # '示例5'
+
+## 使用低于 v4.0.0 版本的 `graphql-request`
+
+可以在 `GraphQLClient` 构造函数中设置 `AbortSignal`。
+
+[//]: # '示例6'
+
+```tsx
+const query = useQuery({
+ queryKey: ['todos'],
+ queryFn: ({ signal }) => {
+ const client = new GraphQLClient(endpoint, {
+ signal,
+ })
+ return client.request(query, variables)
+ },
+})
+```
+
+[//]: # '示例6'
+
+## 手动取消
+
+您可能需要手动取消查询。例如,如果请求耗时过长,可以允许用户点击取消按钮停止请求。只需调用 `queryClient.cancelQueries({ queryKey })` 即可取消查询并回退到之前的状态。如果您消费了传递给查询函数的 `signal`,TanStack Query 还会额外取消 Promise。
+
+[//]: # '示例7'
+
+```tsx
+const query = useQuery({
+ queryKey: ['todos'],
+ queryFn: async ({ signal }) => {
+ const resp = await fetch('/todos', { signal })
+ return resp.json()
+ },
+})
+
+const queryClient = useQueryClient()
+
+return (
+ {
+ e.preventDefault()
+ queryClient.cancelQueries({ queryKey: ['todos'] })
+ }}
+ >
+ 取消
+
+)
+```
+
+[//]: # '示例7'
+
+## 限制
+
+当使用 `Suspense` 钩子时,取消功能不可用:`useSuspenseQuery`、`useSuspenseQueries` 和 `useSuspenseInfiniteQuery`。
diff --git a/docs/zh-hans/framework/react/guides/query-functions.md b/docs/zh-hans/framework/react/guides/query-functions.md
new file mode 100644
index 00000000000..04e8d20cd89
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/query-functions.md
@@ -0,0 +1,121 @@
+---
+source-updated-at: '2025-03-18T08:45:11.000Z'
+translation-updated-at: '2025-05-06T04:09:46.316Z'
+id: query-functions
+title: 查询函数
+---
+
+# 查询函数 (Query Functions)
+
+查询函数可以是**任何返回 Promise 的函数**。返回的 Promise 应当**解析数据 (resolve the data)** 或**抛出错误 (throw an error)**。
+
+以下都是有效的查询函数配置方式:
+
+[//]: # 'Example'
+
+```tsx
+useQuery({ queryKey: ['todos'], queryFn: fetchAllTodos })
+useQuery({ queryKey: ['todos', todoId], queryFn: () => fetchTodoById(todoId) })
+useQuery({
+ queryKey: ['todos', todoId],
+ queryFn: async () => {
+ const data = await fetchTodoById(todoId)
+ return data
+ },
+})
+useQuery({
+ queryKey: ['todos', todoId],
+ queryFn: ({ queryKey }) => fetchTodoById(queryKey[1]),
+})
+```
+
+[//]: # 'Example'
+
+## 错误处理与抛出
+
+为了让 TanStack Query 判定查询发生了错误,查询函数**必须抛出错误**或返回一个**被拒绝的 Promise (rejected Promise)**。在查询函数中抛出的任何错误都会被持久化到查询的 `error` 状态中。
+
+[//]: # 'Example2'
+
+```tsx
+const { error } = useQuery({
+ queryKey: ['todos', todoId],
+ queryFn: async () => {
+ if (somethingGoesWrong) {
+ throw new Error('Oh no!')
+ }
+ if (somethingElseGoesWrong) {
+ return Promise.reject(new Error('Oh no!'))
+ }
+
+ return data
+ },
+})
+```
+
+[//]: # 'Example2'
+
+## 与 `fetch` 等默认不抛出错误的客户端一起使用
+
+虽然大多数工具如 `axios` 或 `graphql-request` 会自动为不成功的 HTTP 调用抛出错误,但像 `fetch` 这样的工具默认不会抛出错误。如果是这种情况,你需要自行抛出错误。以下是使用流行的 `fetch` API 实现这一点的简单方法:
+
+[//]: # 'Example3'
+
+```tsx
+useQuery({
+ queryKey: ['todos', todoId],
+ queryFn: async () => {
+ const response = await fetch('/todos/' + todoId)
+ if (!response.ok) {
+ throw new Error('Network response was not ok')
+ }
+ return response.json()
+ },
+})
+```
+
+[//]: # 'Example3'
+
+## 查询函数变量 (Query Function Variables)
+
+查询键 (Query keys) 不仅用于唯一标识你要获取的数据,还会作为 QueryFunctionContext 的一部分方便地传递到你的查询函数中。虽然并非总是必要,但这使得在需要时可以提取查询函数:
+
+[//]: # 'Example4'
+
+```tsx
+function Todos({ status, page }) {
+ const result = useQuery({
+ queryKey: ['todos', { status, page }],
+ queryFn: fetchTodoList,
+ })
+}
+
+// 在查询函数中访问 key、status 和 page 变量!
+function fetchTodoList({ queryKey }) {
+ const [_key, { status, page }] = queryKey
+ return new Promise()
+}
+```
+
+[//]: # 'Example4'
+
+### 查询函数上下文 (QueryFunctionContext)
+
+`QueryFunctionContext` 是传递给每个查询函数的对象,包含以下属性:
+
+- `queryKey: QueryKey`: [查询键 (Query Keys)](./query-keys.md)
+- `client: QueryClient`: [QueryClient](../../../reference/QueryClient.md)
+- `signal?: AbortSignal`
+ - 由 TanStack Query 提供的 [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) 实例
+ - 可用于 [查询取消 (Query Cancellation)](./query-cancellation.md)
+- `meta: Record | undefined`
+ - 可选字段,可填充有关查询的附加信息
+
+此外,[无限查询 (Infinite Queries)](./infinite-queries.md) 还会传递以下选项:
+
+- `pageParam: TPageParam`
+ - 用于获取当前页面的页面参数
+- `direction: 'forward' | 'backward'`
+ - **已弃用**
+ - 当前页面获取的方向
+ - 要获取当前页面获取的方向,请从 `getNextPageParam` 和 `getPreviousPageParam` 向 `pageParam` 添加方向信息
diff --git a/docs/zh-hans/framework/react/guides/query-invalidation.md b/docs/zh-hans/framework/react/guides/query-invalidation.md
new file mode 100644
index 00000000000..96872646514
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/query-invalidation.md
@@ -0,0 +1,137 @@
+---
+source-updated-at: '2025-03-25T15:32:47.000Z'
+translation-updated-at: '2025-05-06T04:09:50.856Z'
+id: query-invalidation
+title: 查询失效
+---
+
+## 查询失效 (Query Invalidation)
+
+单纯等待查询因陈旧而重新获取并不总是有效,特别是当您明确知道由于用户操作导致某查询数据已过期时。为此,`QueryClient` 提供了 `invalidateQueries` 方法,允许您智能地将查询标记为陈旧状态,并可能触发重新获取!
+
+[//]: # '示例'
+
+```tsx
+// 使缓存中的所有查询失效
+queryClient.invalidateQueries()
+// 使所有以 `todos` 开头的键的查询失效
+queryClient.invalidateQueries({ queryKey: ['todos'] })
+```
+
+[//]: # '示例'
+
+> 注意:其他使用规范化缓存 (normalized caches) 的库会尝试通过命令式或模式推断来用新数据更新本地查询,而 TanStack Query 则为您提供工具来避免维护规范化缓存所需的手动操作,转而采用**定向失效、后台重新获取及最终的原子级更新**策略。
+
+当使用 `invalidateQueries` 使查询失效时,会发生两件事:
+
+- 该查询被标记为陈旧。此状态会覆盖 `useQuery` 或相关钩子中配置的任何 `staleTime` 值
+- 如果该查询当前正通过 `useQuery` 或相关钩子渲染,还会在后台触发重新获取
+
+## 通过 `invalidateQueries` 进行查询匹配
+
+在使用 `invalidateQueries`、`removeQueries` 等支持部分查询匹配的 API 时,您可以通过前缀匹配多个查询,或精确匹配特定查询。关于可使用的过滤器类型,请参阅[查询过滤器](./filters.md#query-filters)。
+
+以下示例中,我们使用 `todos` 前缀来使所有查询键以 `todos` 开头的查询失效:
+
+[//]: # '示例2'
+
+```tsx
+import { useQuery, useQueryClient } from '@tanstack/react-query'
+
+// 从上下文中获取 QueryClient
+const queryClient = useQueryClient()
+
+queryClient.invalidateQueries({ queryKey: ['todos'] })
+
+// 下面的两个查询都将失效
+const todoListQuery = useQuery({
+ queryKey: ['todos'],
+ queryFn: fetchTodoList,
+})
+const todoListQuery = useQuery({
+ queryKey: ['todos', { page: 1 }],
+ queryFn: fetchTodoList,
+})
+```
+
+[//]: # '示例2'
+
+您还可以通过向 `invalidateQueries` 方法传递更具体的查询键,来使带有特定变量的查询失效:
+
+[//]: # '示例3'
+
+```tsx
+queryClient.invalidateQueries({
+ queryKey: ['todos', { type: 'done' }],
+})
+
+// 下面的查询将失效
+const todoListQuery = useQuery({
+ queryKey: ['todos', { type: 'done' }],
+ queryFn: fetchTodoList,
+})
+
+// 但下面的查询不会失效
+const todoListQuery = useQuery({
+ queryKey: ['todos'],
+ queryFn: fetchTodoList,
+})
+```
+
+[//]: # '示例3'
+
+`invalidateQueries` API 非常灵活,如果您**只想**使那些没有额外变量或子键的 `todos` 查询失效,可以向 `invalidateQueries` 方法传递 `exact: true` 选项:
+
+[//]: # '示例4'
+
+```tsx
+queryClient.invalidateQueries({
+ queryKey: ['todos'],
+ exact: true,
+})
+
+// 下面的查询将失效
+const todoListQuery = useQuery({
+ queryKey: ['todos'],
+ queryFn: fetchTodoList,
+})
+
+// 但下面的查询不会失效
+const todoListQuery = useQuery({
+ queryKey: ['todos', { type: 'done' }],
+ queryFn: fetchTodoList,
+})
+```
+
+[//]: # '示例4'
+
+如果需要**更精细**的控制,可以向 `invalidateQueries` 方法传递一个断言函数。该函数会接收查询缓存中的每个 `Query` 实例,您可以通过返回 `true` 或 `false` 来决定是否使该查询失效:
+
+[//]: # '示例5'
+
+```tsx
+queryClient.invalidateQueries({
+ predicate: (query) =>
+ query.queryKey[0] === 'todos' && query.queryKey[1]?.version >= 10,
+})
+
+// 下面的查询将失效
+const todoListQuery = useQuery({
+ queryKey: ['todos', { version: 20 }],
+ queryFn: fetchTodoList,
+})
+
+// 下面的查询将失效
+const todoListQuery = useQuery({
+ queryKey: ['todos', { version: 10 }],
+ queryFn: fetchTodoList,
+})
+
+// 但下面的查询不会失效
+const todoListQuery = useQuery({
+ queryKey: ['todos', { version: 5 }],
+ queryFn: fetchTodoList,
+})
+```
+
+[//]: # '示例5'
diff --git a/docs/zh-hans/framework/react/guides/query-keys.md b/docs/zh-hans/framework/react/guides/query-keys.md
new file mode 100644
index 00000000000..84afe70d858
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/query-keys.md
@@ -0,0 +1,104 @@
+---
+source-updated-at: '2025-03-18T08:45:11.000Z'
+translation-updated-at: '2025-05-06T04:09:40.213Z'
+id: query-keys
+title: 查询键
+---
+
+TanStack Query 的核心是基于查询键 (query keys) 为你管理查询缓存。查询键在顶层必须是一个数组,可以简单到只包含单个字符串的数组,也可以复杂到包含多个字符串和嵌套对象的数组。只要查询键是可序列化的,并且**能唯一标识查询的数据**,你就可以使用它!
+
+## 简单查询键
+
+最简单的键形式是由常量值组成的数组。这种格式适用于:
+
+- 通用列表/索引资源
+- 非层级化资源
+
+[//]: # '示例'
+
+```tsx
+// 待办事项列表
+useQuery({ queryKey: ['todos'], ... })
+
+// 其他任意内容!
+useQuery({ queryKey: ['something', 'special'], ... })
+```
+
+[//]: # '示例'
+
+## 带变量的数组键
+
+当查询需要更多信息来唯一描述其数据时,你可以使用包含字符串和任意数量可序列化对象的数组。这适用于:
+
+- 层级化或嵌套资源
+ - 通常会传递 ID、索引或其他原始值来唯一标识项目
+- 带附加参数的查询
+ - 通常会传递包含附加选项的对象
+
+[//]: # '示例2'
+
+```tsx
+// 单个待办事项
+useQuery({ queryKey: ['todo', 5], ... })
+
+// "预览"格式的单个待办事项
+useQuery({ queryKey: ['todo', 5, { preview: true }], ...})
+
+// 已完成的待办事项列表
+useQuery({ queryKey: ['todos', { type: 'done' }], ... })
+```
+
+[//]: # '示例2'
+
+## 查询键会被确定性地哈希处理!
+
+这意味着无论对象中键的顺序如何,以下所有查询都被视为相等:
+
+[//]: # '示例3'
+
+```tsx
+useQuery({ queryKey: ['todos', { status, page }], ... })
+useQuery({ queryKey: ['todos', { page, status }], ...})
+useQuery({ queryKey: ['todos', { page, status, other: undefined }], ... })
+```
+
+[//]: # '示例3'
+
+然而以下查询键并不相等。数组项的顺序很重要!
+
+[//]: # '示例4'
+
+```tsx
+useQuery({ queryKey: ['todos', status, page], ... })
+useQuery({ queryKey: ['todos', page, status], ...})
+useQuery({ queryKey: ['todos', undefined, page, status], ...})
+```
+
+[//]: # '示例4'
+
+## 如果查询函数依赖变量,请将其包含在查询键中
+
+由于查询键唯一描述了它们获取的数据,因此应该包含查询函数中使用的任何**会变化**的变量。例如:
+
+[//]: # '示例5'
+
+```tsx
+function Todos({ todoId }) {
+ const result = useQuery({
+ queryKey: ['todos', todoId],
+ queryFn: () => fetchTodoById(todoId),
+ })
+}
+```
+
+[//]: # '示例5'
+
+请注意,查询键充当查询函数的依赖项。将依赖变量添加到查询键中可确保查询被独立缓存,并且每当变量变化时,_查询会自动重新获取_(取决于你的 `staleTime` 设置)。更多信息和示例请参阅[全面依赖项](../../../eslint/exhaustive-deps.md)部分。
+
+[//]: # '材料'
+
+## 延伸阅读
+
+关于在大型应用中组织查询键的技巧,请参阅[高效 React Query 键](../community/tkdodos-blog.md#8-effective-react-query-keys),并查看社区资源中的[查询键工厂包](../community/community-projects.md#query-key-factory)。
+
+[//]: # '材料'
diff --git a/docs/zh-hans/framework/react/guides/query-options.md b/docs/zh-hans/framework/react/guides/query-options.md
new file mode 100644
index 00000000000..31bd4307785
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/query-options.md
@@ -0,0 +1,53 @@
+---
+source-updated-at: '2025-03-18T08:45:11.000Z'
+translation-updated-at: '2025-05-06T04:06:24.141Z'
+id: query-options
+title: 查询选项
+---
+
+## 查询选项 (Query Options)
+
+在多个地方共享 `queryKey` 和 `queryFn` 同时保持它们彼此关联的最佳方式之一是使用 `queryOptions` 辅助函数。在运行时,这个辅助函数仅返回你传入的内容,但[配合 TypeScript 使用时](../typescript.md#typing-query-options)它能带来诸多优势。你可以在一个地方定义查询的所有可能选项,并同时获得完整的类型推断和类型安全。
+
+[//]: # 'Example1'
+
+```ts
+import { queryOptions } from '@tanstack/react-query'
+
+function groupOptions(id: number) {
+ return queryOptions({
+ queryKey: ['groups', id],
+ queryFn: () => fetchGroups(id),
+ staleTime: 5 * 1000,
+ })
+}
+
+// 使用示例:
+
+useQuery(groupOptions(1))
+useSuspenseQuery(groupOptions(5))
+useQueries({
+ queries: [groupOptions(1), groupOptions(2)],
+})
+queryClient.prefetchQuery(groupOptions(23))
+queryClient.setQueryData(groupOptions(42).queryKey, newGroups)
+```
+
+[//]: # 'Example1'
+
+对于无限查询 (Infinite Queries),可以使用单独的 [`infiniteQueryOptions`](../reference/infiniteQueryOptions.md) 辅助函数。
+
+你仍然可以在组件级别覆盖某些选项。一个非常常见且实用的模式是为每个组件创建 [`select`](./render-optimizations.md#select) 函数:
+
+[//]: # 'Example2'
+
+```ts
+// 类型推断仍然有效,因此 query.data 将是 select 的返回类型而非 queryFn 的返回类型
+
+const query = useQuery({
+ ...groupOptions(1),
+ select: (data) => data.groupName,
+})
+```
+
+[//]: # 'Example2'
diff --git a/docs/zh-hans/framework/react/guides/query-retries.md b/docs/zh-hans/framework/react/guides/query-retries.md
new file mode 100644
index 00000000000..4b964ad9422
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/query-retries.md
@@ -0,0 +1,82 @@
+---
+source-updated-at: '2024-01-25T20:57:22.000Z'
+translation-updated-at: '2025-05-06T04:04:04.683Z'
+id: query-retries
+title: 查询重试
+---
+
+当 `useQuery` 查询失败(查询函数抛出错误)时,如果该查询的请求未达到最大连续重试次数(默认为 `3`)或提供了判断是否允许重试的函数,TanStack Query 会自动重试该查询。
+
+您可以在全局级别和单个查询级别配置重试行为:
+
+- 设置 `retry = false` 将禁用重试
+- 设置 `retry = 6` 会在显示函数抛出的最终错误前重试失败请求 6 次
+- 设置 `retry = true` 会无限重试失败请求
+- 设置 `retry = (failureCount, error) => ...` 允许根据失败原因自定义重试逻辑
+
+[//]: # 'Info'
+
+> 在服务端,重试默认值为 `0` 以确保服务端渲染尽可能快速
+
+[//]: # 'Info'
+[//]: # 'Example'
+
+```tsx
+import { useQuery } from '@tanstack/react-query'
+
+// 让特定查询重试指定次数
+const result = useQuery({
+ queryKey: ['todos', 1],
+ queryFn: fetchTodoListPage,
+ retry: 10, // 将在显示错误前重试失败请求 10 次
+})
+```
+
+[//]: # 'Example'
+
+> 注意:在最后一次重试尝试前,`error` 属性的内容将作为 `failureReason` 响应属性存在于 `useQuery` 中。因此在上例中,前 9 次重试尝试(共 10 次)的任何错误内容都将属于 `failureReason` 属性,只有当所有重试尝试后错误仍然存在时,最终才会出现在 `error` 属性中。
+
+## 重试延迟
+
+默认情况下,TanStack Query 不会在请求失败后立即重试。按照标准做法,每次重试尝试都会逐渐增加退避延迟。
+
+默认的 `retryDelay` 设置为每次尝试翻倍(从 `1000` 毫秒开始),但不超过 30 秒:
+
+[//]: # 'Example2'
+
+```tsx
+// 为所有查询配置
+import {
+ QueryCache,
+ QueryClient,
+ QueryClientProvider,
+} from '@tanstack/react-query'
+
+const queryClient = new QueryClient({
+ defaultOptions: {
+ queries: {
+ retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 30000),
+ },
+ },
+})
+
+function App() {
+ return ...
+}
+```
+
+[//]: # 'Example2'
+
+虽然不推荐,但您显然可以在 Provider 和单个查询选项中覆盖 `retryDelay` 函数/整数值。如果设置为整数而非函数,延迟时间将始终保持不变:
+
+[//]: # 'Example3'
+
+```tsx
+const result = useQuery({
+ queryKey: ['todos'],
+ queryFn: fetchTodoList,
+ retryDelay: 1000, // 每次重试都固定等待 1000 毫秒,无论重试次数多少
+})
+```
+
+[//]: # 'Example3'
diff --git a/docs/zh-hans/framework/react/guides/render-optimizations.md b/docs/zh-hans/framework/react/guides/render-optimizations.md
new file mode 100644
index 00000000000..9fcd0acf831
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/render-optimizations.md
@@ -0,0 +1,77 @@
+---
+source-updated-at: '2025-03-18T08:45:11.000Z'
+translation-updated-at: '2025-05-06T04:04:41.928Z'
+id: render-optimizations
+title: 渲染优化
+---
+
+React Query 自动应用多项优化策略,确保组件仅在真正需要时重新渲染。这主要通过以下方式实现:
+
+## 结构共享 (structural sharing)
+
+React Query 采用称为"结构共享"的技术,尽可能在重新渲染间保持引用不变。当通过网络获取数据时,通常通过 JSON 解析响应会得到全新引用。但若数据内容未变化,React Query 会保留原始引用;若仅部分数据变更,则保留未变更部分,仅替换变更部分。
+
+> 注意:此优化仅在 `queryFn` 返回 JSON 兼容数据时生效。可通过全局或单查询设置 `structuralSharing: false` 关闭该功能,也可通过传入自定义函数实现个性化结构共享。
+
+### 引用一致性 (referential identity)
+
+从 `useQuery`、`useInfiniteQuery`、`useMutation` 返回的顶层对象及 `useQueries` 返回的数组**不具备引用稳定性**——每次渲染都会生成新引用。但这些钩子返回的 `data` 属性会尽可能保持稳定。
+
+## 属性追踪 (tracked properties)
+
+React Query 仅当组件实际"使用"了 `useQuery` 返回的某个属性时才会触发重新渲染,这是通过[自定义 getter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty#custom_setters_and_getters)实现的。该机制避免了许多不必要的重渲染(例如 `isFetching` 或 `isStale` 等频繁变更但未被使用的属性)。
+
+可通过全局或单查询设置 `notifyOnChangeProps` 自定义此功能。若要完全关闭,可设为 `notifyOnChangeProps: 'all'`。
+
+> 注意:自定义 getter 需通过解构或直接访问属性触发。若使用对象剩余解构会禁用此优化,我们提供了 [lint 规则](../../../eslint/no-rest-destructuring.md)防止此问题。
+
+## 选择器 (select)
+
+通过 `select` 选项可指定组件应订阅的数据子集,适用于高度优化的数据转换或避免不必要重渲染场景:
+
+```js
+export const useTodos = (select) => {
+ return useQuery({
+ queryKey: ['todos'],
+ queryFn: fetchTodos,
+ select,
+ })
+}
+
+export const useTodoCount = () => {
+ return useTodos((data) => data.length)
+}
+```
+
+使用 `useTodoCount` 自定义钩子的组件仅当待办事项数量变化时重渲染,而单个待办事项名称变更等操作不会触发重渲染。
+
+> 注意:`select` 操作基于成功缓存的数据,不适合用于抛出错误。错误应源自 `queryFn`,若 `select` 函数返回错误会导致 `data` 为 `undefined` 而 `isSuccess` 为 `true`。建议在 `queryFn` 中处理数据错误,或在查询钩子外部处理与缓存无关的异常情况。
+
+### 记忆化 (memoization)
+
+`select` 函数仅在以下情况重新执行:
+
+- 函数引用发生变化
+- `data` 发生变化
+
+因此如上例所示的行内 `select` 函数会在每次渲染时执行。为避免这种情况,可用 `useCallback` 包裹,或在无依赖时提取为稳定函数引用:
+
+```js
+// 使用 useCallback 包裹
+export const useTodoCount = () => {
+ return useTodos(useCallback((data) => data.length, []))
+}
+```
+
+```js
+// 提取为稳定函数引用
+const selectTodoCount = (data) => data.length
+
+export const useTodoCount = () => {
+ return useTodos(selectTodoCount)
+}
+```
+
+## 延伸阅读
+
+关于这些主题的深度指南,请参阅社区资源中的 [React Query 渲染优化](../community/tkdodos-blog.md#3-react-query-render-optimizations)。
diff --git a/docs/zh-hans/framework/react/guides/request-waterfalls.md b/docs/zh-hans/framework/react/guides/request-waterfalls.md
new file mode 100644
index 00000000000..178aeacfa5f
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/request-waterfalls.md
@@ -0,0 +1,340 @@
+---
+source-updated-at: '2025-04-02T06:46:03.000Z'
+translation-updated-at: '2025-05-06T04:11:08.176Z'
+id: request-waterfalls
+title: 性能与请求瀑布流
+---
+
+应用性能是一个广泛而复杂的领域,虽然 React Query 无法让你的 API 变得更快,但在使用 React Query 时仍需注意一些事项以确保最佳性能。
+
+使用 React Query 或任何允许在组件内部获取数据的库时,最大的性能隐患是**请求瀑布流**。本页剩余部分将解释什么是请求瀑布流、如何发现它们,以及如何重构应用或 API 来避免它们。
+
+[预取与路由集成指南](./prefetching.md)在此基础上进一步讲解,教你如何在无法或不适合重构应用或 API 时提前预取数据。
+
+[服务端渲染与注水指南](./ssr.md)教你如何在服务端预取数据并将其传递到客户端,从而避免重复获取。
+
+[高级服务端渲染指南](./advanced-ssr.md)进一步讲解如何将这些模式应用到服务端组件 (Server Components) 和流式服务端渲染 (Streaming Server Rendering) 中。
+
+## 什么是请求瀑布流?
+
+请求瀑布流指的是当某个资源(代码、CSS、图片、数据)的请求必须等待另一个资源的请求完成后才能开始。
+
+以网页为例。在加载 CSS、JS 等内容之前,浏览器需要先加载标记 (markup)。这就是一个请求瀑布流:
+
+```
+1. |-> Markup
+2. |-> CSS
+2. |-> JS
+2. |-> Image
+```
+
+如果在 JS 文件中获取 CSS,就会形成双重瀑布流:
+
+```
+1. |-> Markup
+2. |-> JS
+3. |-> CSS
+```
+
+如果该 CSS 使用了背景图片,则形成三重瀑布流:
+
+```
+1. |-> Markup
+2. |-> JS
+3. |-> CSS
+4. |-> Image
+```
+
+发现和分析请求瀑布流的最佳方式通常是打开浏览器开发者工具的“网络 (Network)”选项卡。
+
+每个瀑布流至少代表一次与服务器的往返通信(除非资源被本地缓存)。因此,请求瀑布流的负面影响高度依赖用户的网络延迟。以前面的三重瀑布流为例,它实际上代表 4 次服务器往返。在 250ms 延迟(3G 网络或恶劣网络条件下很常见)的情况下,仅计算延迟时间就达到 4\*250=1000ms。如果能将其优化为第一个示例中的仅 2 次往返,延迟时间将降至 500ms,背景图片的加载时间可能缩短一半!
+
+## 请求瀑布流与 React Query
+
+现在来看 React Query 的情况。我们首先关注不使用服务端渲染的场景。在发起查询之前需要先加载 JS,因此在屏幕上显示数据之前会形成双重瀑布流:
+
+```
+1. |-> Markup
+2. |-> JS
+3. |-> Query
+```
+
+以此为基准,下面分析几种可能导致 React Query 请求瀑布流的模式及规避方法:
+
+- 单组件瀑布流 / 串行查询
+- 嵌套组件瀑布流
+- 代码分割
+
+### 单组件瀑布流 / 串行查询
+
+当一个组件先获取一个查询,再获取另一个查询时,就会形成请求瀑布流。这种情况常出现在第二个查询是[依赖查询 (Dependent Query)](./dependent-queries.md)时——即它依赖第一个查询的数据来发起请求:
+
+```tsx
+// 获取用户
+const { data: user } = useQuery({
+ queryKey: ['user', email],
+ queryFn: getUserByEmail,
+})
+
+const userId = user?.id
+
+// 然后获取用户的项目
+const {
+ status,
+ fetchStatus,
+ data: projects,
+} = useQuery({
+ queryKey: ['projects', userId],
+ queryFn: getProjectsByUser,
+ // 该查询在 userId 存在前不会执行
+ enabled: !!userId,
+})
+```
+
+虽然并非总能实现,但为了最佳性能,最好重构 API 以便通过单个查询获取这两项数据。在上例中,与其先获取 `getUserByEmail` 才能调用 `getProjectsByUser`,不如新增一个 `getProjectsByUserEmail` 查询来消除瀑布流。
+
+> 另一种在不重构 API 的情况下缓解依赖查询的方法是:将瀑布流转移到延迟更低的服务端。这是[高级服务端渲染指南](./advanced-ssr.md)中介绍的服务端组件 (Server Components) 的设计理念。
+
+使用 React Query 的 Suspense 时也会出现串行查询:
+
+```tsx
+function App () {
+ // 以下查询会串行执行,导致多次服务器往返:
+ const usersQuery = useSuspenseQuery({ queryKey: ['users'], queryFn: fetchUsers })
+ const teamsQuery = useSuspenseQuery({ queryKey: ['teams'], queryFn: fetchTeams })
+ const projectsQuery = useSuspenseQuery({ queryKey: ['projects'], queryFn: fetchProjects })
+
+ // 注意:由于上述查询会暂停渲染,所有查询完成前不会渲染任何数据
+ ...
+}
+```
+
+注意:使用常规 `useQuery` 时这些查询会并行执行。
+
+幸运的是,这个问题很容易修复——当组件中有多个 Suspense 查询时,始终使用 `useSuspenseQueries` 钩子:
+
+```tsx
+const [usersQuery, teamsQuery, projectsQuery] = useSuspenseQueries({
+ queries: [
+ { queryKey: ['users'], queryFn: fetchUsers },
+ { queryKey: ['teams'], queryFn: fetchTeams },
+ { queryKey: ['projects'], queryFn: fetchProjects },
+ ],
+})
+```
+
+### 嵌套组件瀑布流
+
+当父组件和子组件都包含查询,且父组件在查询完成前不会渲染子组件时,就会出现嵌套组件瀑布流。这种情况可能发生在 `useQuery` 和 `useSuspenseQuery` 中。
+
+如果子组件的渲染依赖于父组件的数据,或者子组件需要父组件传递部分结果作为 prop 才能发起查询,就形成了**依赖型**嵌套组件瀑布流。
+
+首先看一个子组件**不依赖**父组件的例子:
+
+```tsx
+function Article({ id }) {
+ const { data: articleData, isPending } = useQuery({
+ queryKey: ['article', id],
+ queryFn: getArticleById,
+ })
+
+ if (isPending) {
+ return 'Loading article...'
+ }
+
+ return (
+ <>
+
+
+
+ >
+ )
+
+}
+
+function Comments({ id }) {
+ const { data, isPending } = useQuery({
+ queryKey: ['article-comments', id],
+ queryFn: getArticleCommentsById,
+ })
+
+ ...
+}
+```
+
+注意:虽然 `` 接收父组件传递的 `id` prop,但这个 id 在 `` 渲染时已经可用,因此没有理由不能同时获取评论和文章数据。在实际应用中,子组件可能嵌套在父组件多层级之下,这类瀑布流更难发现和修复。但在本例中,一种消除瀑布流的方法是将评论查询提升到父组件:
+
+```tsx
+function Article({ id }) {
+ const { data: articleData, isPending: articlePending } = useQuery({
+ queryKey: ['article', id],
+ queryFn: getArticleById,
+ })
+
+ const { data: commentsData, isPending: commentsPending } = useQuery({
+ queryKey: ['article-comments', id],
+ queryFn: getArticleCommentsById,
+ })
+
+ if (articlePending) {
+ return 'Loading article...'
+ }
+
+ return (
+ <>
+
+
+ {commentsPending ? (
+ 'Loading comments...'
+ ) : (
+
+ )}
+ >
+ )
+}
+```
+
+现在两个查询会并行执行。注意:如果使用 Suspense,应该改用 `useSuspenseQueries` 合并这两个查询。
+
+另一种消除瀑布流的方法是在 `` 组件中预取评论,或者在路由级别预取这两个查询(页面加载或导航时)。更多细节请参阅[预取与路由集成指南](./prefetching.md)。
+
+接下来看一个**依赖型**嵌套组件瀑布流的例子:
+
+```tsx
+function Feed() {
+ const { data, isPending } = useQuery({
+ queryKey: ['feed'],
+ queryFn: getFeed,
+ })
+
+ if (isPending) {
+ return 'Loading feed...'
+ }
+
+ return (
+ <>
+ {data.map((feedItem) => {
+ if (feedItem.type === 'GRAPH') {
+ return
+ }
+
+ return
+ })}
+ >
+ )
+}
+
+function GraphFeedItem({ feedItem }) {
+ const { data, isPending } = useQuery({
+ queryKey: ['graph', feedItem.id],
+ queryFn: getGraphDataById,
+ })
+
+ ...
+}
+```
+
+第二个查询 `getGraphDataById` 在两方面依赖父组件:首先,只有当 `feedItem` 是图表类型时才会执行;其次,它需要父组件传递的 `id`。
+
+```
+1. |> getFeed()
+2. |> getGraphDataById()
+```
+
+在这个例子中,我们无法简单地通过将查询提升到父组件或添加预取来消除瀑布流。就像本指南开头的依赖查询示例一样,一种选择是重构 API 让 `getFeed` 查询包含图表数据。另一种更高级的解决方案是利用服务端组件 (Server Components) 将瀑布流转移到延迟更低的服务端(详见[高级服务端渲染指南](./advanced-ssr.md)),但要注意这可能涉及重大的架构变更。
+
+即使存在少量查询瀑布流,应用仍能保持良好的性能。关键是要意识到这是常见的性能问题并保持警惕。当涉及代码分割时,情况会变得更加棘手,下面就来分析这种情况。
+
+### 代码分割
+
+将应用的 JS 代码拆分为更小的块并仅加载必要部分,通常是实现良好性能的关键步骤。但这也有缺点——常常会引入请求瀑布流。当被分割的代码中还包含查询时,问题会进一步加剧。
+
+来看一个稍作修改的 Feed 示例:
+
+```tsx
+// 延迟加载 GraphFeedItem 组件,意味着在渲染前不会开始加载
+const GraphFeedItem = React.lazy(() => import('./GraphFeedItem'))
+
+function Feed() {
+ const { data, isPending } = useQuery({
+ queryKey: ['feed'],
+ queryFn: getFeed,
+ })
+
+ if (isPending) {
+ return 'Loading feed...'
+ }
+
+ return (
+ <>
+ {data.map((feedItem) => {
+ if (feedItem.type === 'GRAPH') {
+ return
+ }
+
+ return
+ })}
+ >
+ )
+}
+
+// GraphFeedItem.tsx
+function GraphFeedItem({ feedItem }) {
+ const { data, isPending } = useQuery({
+ queryKey: ['graph', feedItem.id],
+ queryFn: getGraphDataById,
+ })
+
+ ...
+}
+```
+
+这个例子形成了双重瀑布流:
+
+```
+1. |> getFeed()
+2. |> JS for
+3. |> getGraphDataById()
+```
+
+但仅从代码角度看是这样。如果考虑该页面的首次加载过程,实际上需要完成 5 次服务器往返才能渲染图表:
+
+```
+1. |> Markup
+2. |> JS for
+3. |> getFeed()
+4. |> JS for
+5. |> getGraphDataById()
+```
+
+注意:服务端渲染时情况会有所不同,我们将在[服务端渲染与注水指南](./ssr.md)中详细探讨。另外要注意的是,包含 `` 的路由通常也会被代码分割,这可能又增加一次跳转。
+
+对于代码分割的情况,将 `getGraphDataById` 查询提升到 `` 组件并设为条件查询,或添加条件预取可能有所帮助。这样该查询可以与代码并行获取,将示例部分转变为:
+
+```
+1. |> getFeed()
+2. |> getGraphDataById()
+2. |> JS for
+```
+
+但这是一种权衡——现在 `getGraphDataById` 的数据获取代码被打包进了 `` 的主包中。请根据具体情况评估最佳方案。更多实现方法请参阅[预取与路由集成指南](./prefetching.md)。
+
+> 以下两种方案的权衡:
+>
+> - 将所有数据获取代码包含在主包中,即使很少使用
+> - 将数据获取代码放在分割包中,但会产生请求瀑布流
+>
+> 并不理想,这也是服务端组件 (Server Components) 的设计动机之一。通过服务端组件可以同时避免这两个问题,更多与 React Query 的结合应用请参阅[高级服务端渲染指南](./advanced-ssr.md)。
+
+## 总结与要点
+
+请求瀑布流是一个非常常见且复杂的性能问题,涉及多种权衡。应用中可能意外引入瀑布流的方式包括:
+
+- 在子组件中添加查询,未意识到父组件已有查询
+- 在父组件中添加查询,未意识到子组件已有查询
+- 将带有查询的组件及其后代移动到已有查询的新父组件中
+- 等等...
+
+由于这种意外复杂性,保持对瀑布流的警惕并定期检查应用(一个好方法是时不时检查网络选项卡!)是非常值得的。不一定要消除所有瀑布流才能获得良好性能,但要特别关注那些影响重大的情况。
+
+在下一指南中,我们将通过[预取与路由集成](./prefetching.md)探索更多消除瀑布流的方法。
diff --git a/docs/zh-hans/framework/react/guides/scroll-restoration.md b/docs/zh-hans/framework/react/guides/scroll-restoration.md
new file mode 100644
index 00000000000..039cb6b7caa
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/scroll-restoration.md
@@ -0,0 +1,12 @@
+---
+source-updated-at: '2024-01-25T20:57:22.000Z'
+translation-updated-at: '2025-05-06T04:09:15.717Z'
+id: scroll-restoration
+title: 滚动恢复
+---
+
+## 滚动恢复 (Scroll Restoration)
+
+传统上,当你在网页浏览器中导航回之前访问过的页面时,会发现页面会自动滚动到你上次离开时的位置。这一功能被称为 **滚动恢复 (scroll restoration)**。但随着现代 Web 应用逐渐转向客户端数据获取 (client side data fetching),这一特性曾出现了一定程度的退化。不过在使用 TanStack Query 时,情况就完全不同了。
+
+开箱即用,所有查询(包括分页查询和无限加载查询)的"滚动恢复 (scroll restoration)"功能在 TanStack Query 中都能完美运作™️。这是因为查询结果会被缓存,并且在组件渲染时可以同步获取。只要你的查询缓存时间足够长(默认缓存时间为 5 分钟)且未被垃圾回收机制清除,滚动恢复功能就能始终正常工作。
diff --git a/docs/zh-hans/framework/react/guides/ssr.md b/docs/zh-hans/framework/react/guides/ssr.md
new file mode 100644
index 00000000000..de6e57e69df
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/ssr.md
@@ -0,0 +1,485 @@
+---
+source-updated-at: '2025-04-02T06:46:03.000Z'
+translation-updated-at: '2025-05-06T04:09:15.592Z'
+id: ssr
+title: 服务端渲染与注水
+---
+
+# 服务端渲染与注水 (Server Rendering & Hydration)
+
+在本指南中,您将学习如何结合服务端渲染使用 React Query。
+
+关于背景知识,请参阅[预取与路由集成](./prefetching.md)指南。在此之前,您可能还需要查看[性能与请求瀑布流指南](./request-waterfalls.md)。
+
+如需了解高级服务端渲染模式(如流式传输、服务器组件和新的 Next.js app router),请参阅[高级服务端渲染指南](./advanced-ssr.md)。
+
+如果您只想查看代码示例,可以直接跳转到下方的[完整 Next.js pages router 示例](#full-nextjs-pages-router-example)或[完整 Remix 示例](#full-remix-example)。
+
+## 服务端渲染与 React Query
+
+那么什么是服务端渲染?本指南的其余部分将假设您已熟悉这个概念,但让我们花些时间看看它与 React Query 的关系。服务端渲染是在服务器上生成初始 HTML 的行为,这样用户在页面加载时就能立即看到一些内容。这可以在页面被请求时按需发生(SSR),也可以因为之前的请求被缓存或在构建时(SSG)提前发生。
+
+如果您阅读过请求瀑布流指南,可能会记得这个流程:
+
+```
+1. |-> 标记(无内容)
+2. |-> JavaScript
+3. |-> 查询
+```
+
+在客户端渲染的应用程序中,这是用户在屏幕上看到任何内容之前至少需要进行的 3 次服务器往返。服务端渲染的一种理解方式是将其转变为:
+
+```
+1. |-> 标记(包含内容 AND 初始数据)
+2. |-> JavaScript
+```
+
+一旦 **1.** 完成,用户就可以看到内容,当 **2.** 完成时,页面变得可交互和可点击。因为标记中还包含我们需要的初始数据,所以步骤 **3.** 根本不需要在客户端运行,至少在您因某些原因想要重新验证数据之前不需要。
+
+这都是从客户端的角度来看的。在服务器端,我们需要在生成/渲染标记之前**预取**数据,需要将该数据**脱水**为可序列化的格式以便嵌入到标记中,而在客户端,我们需要将该数据**注水**到 React Query 缓存中,以避免在客户端进行新的获取。
+
+继续阅读以了解如何用 React Query 实现这三个步骤。
+
+## 关于 Suspense 的快速说明
+
+本指南使用常规的 `useQuery` API。虽然我们不一定会推荐,但可以用 `useSuspenseQuery` 替代它,**只要您总是预取所有查询**。这样做的好处是您可以在客户端使用 `` 来处理加载状态。
+
+如果您在使用 `useSuspenseQuery` 时忘记预取查询,后果将取决于您使用的框架。在某些情况下,数据会在服务器端 Suspense 并获取,但永远不会被注水到客户端,客户端会再次获取。在这些情况下,您会遇到标记注水不匹配的问题,因为服务器和客户端尝试渲染不同的内容。
+
+## 初始设置
+
+使用 React Query 的第一步始终是创建一个 `queryClient` 并将应用程序包裹在 `` 中。在进行服务端渲染时,重要的是在您的应用程序内部、React 状态中创建 `queryClient` 实例(实例引用也可以)。**这确保不同用户和请求之间的数据不会共享**,同时仍然只在组件生命周期中创建一次 `queryClient`。
+
+Next.js pages router 示例:
+
+```tsx
+// _app.tsx
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
+
+// 永远不要这样做:
+// const queryClient = new QueryClient()
+//
+// 在文件根级别创建 queryClient 会使缓存
+// 在所有请求之间共享,意味着 _所有_ 数据都会传递给 _所有_ 用户。
+// 除了对性能不利外,这还会泄露任何敏感数据。
+
+export default function MyApp({ Component, pageProps }) {
+ // 应该这样做,确保每个请求都有自己的缓存:
+ const [queryClient] = React.useState(
+ () =>
+ new QueryClient({
+ defaultOptions: {
+ queries: {
+ // 使用 SSR 时,我们通常希望设置默认的 staleTime
+ // 大于 0,以避免在客户端立即重新获取
+ staleTime: 60 * 1000,
+ },
+ },
+ }),
+ )
+
+ return (
+
+
+
+ )
+}
+```
+
+Remix 示例:
+
+```tsx
+// app/root.tsx
+import { Outlet } from '@remix-run/react'
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
+
+export default function MyApp() {
+ const [queryClient] = React.useState(
+ () =>
+ new QueryClient({
+ defaultOptions: {
+ queries: {
+ // 使用 SSR 时,我们通常希望设置默认的 staleTime
+ // 大于 0,以避免在客户端立即重新获取
+ staleTime: 60 * 1000,
+ },
+ },
+ }),
+ )
+
+ return (
+
+
+
+ )
+}
+```
+
+## 使用 `initialData` 快速开始
+
+最快的方法是根本不涉及 React Query 的预取功能,也不使用 `dehydrate`/`hydrate` API。相反,您可以将原始数据作为 `initialData` 选项传递给 `useQuery`。让我们看一个使用 Next.js pages router 和 `getServerSideProps` 的示例。
+
+```tsx
+export async function getServerSideProps() {
+ const posts = await getPosts()
+ return { props: { posts } }
+}
+
+function Posts(props) {
+ const { data } = useQuery({
+ queryKey: ['posts'],
+ queryFn: getPosts,
+ initialData: props.posts,
+ })
+
+ // ...
+}
+```
+
+这也适用于 `getStaticProps` 甚至较旧的 `getInitialProps`,相同的模式可以应用于任何具有等效功能的其他框架。这是在 Remix 中的相同示例:
+
+```tsx
+export async function loader() {
+ const posts = await getPosts()
+ return json({ posts })
+}
+
+function Posts() {
+ const { posts } = useLoaderData()
+
+ const { data } = useQuery({
+ queryKey: ['posts'],
+ queryFn: getPosts,
+ initialData: posts,
+ })
+
+ // ...
+}
+```
+
+设置非常简单,这可以快速解决某些情况,但与完整方法相比,有**一些权衡需要考虑**:
+
+- 如果您在树中更深层的组件中调用 `useQuery`,则需要将 `initialData` 传递到该点
+- 如果您在多个位置使用相同的查询调用 `useQuery`,只将 `initialData` 传递给其中一个可能会很脆弱,并在应用程序更改时中断。如果您删除或移动了带有 `initialData` 的 `useQuery` 的组件,更深的 `useQuery` 可能不再有任何数据。将 `initialData` 传递给**所有**需要它的查询也可能很繁琐。
+- 无法知道查询在服务器上获取的时间,因此 `dataUpdatedAt` 和确定查询是否需要重新获取是基于页面加载时间而不是查询获取时间
+- 如果缓存中已有查询的数据,`initialData` 永远不会覆盖这些数据,**即使新数据比旧数据更新**。
+ - 要理解为什么这特别糟糕,请考虑上面的 `getServerSideProps` 示例。如果您多次导航到页面并返回,`getServerSideProps` 每次都会被调用并获取新数据,但因为使用了 `initialData` 选项,客户端缓存和数据永远不会更新。
+
+设置完整的注水解决方案很简单,并且没有这些缺点,这将是本文档其余部分的重点。
+
+## 使用注水 API
+
+只需稍多的设置,您就可以在预加载阶段使用 `queryClient` 预取查询,将该 `queryClient` 的序列化版本传递给应用程序的渲染部分并在那里重用。这避免了上述缺点。随意跳转到完整的 Next.js pages router 和 Remix 示例,但在一般情况下,这些是额外的步骤:
+
+- 在框架的 loader 函数中,创建 `const queryClient = new QueryClient(options)`
+- 在 loader 函数中,为每个要预取的查询执行 `await queryClient.prefetchQuery(...)`
+ - 您希望尽可能使用 `await Promise.all(...)` 并行获取查询
+ - 可以有不预取的查询。这些不会在服务器端渲染,而是在应用程序变得可交互后在客户端获取。这对于仅在用户交互后显示的内容或位于页面较下方以避免阻塞更关键内容的内容非常有用。
+- 从 loader 返回 `dehydrate(queryClient)`,注意返回此的确切语法因框架而异
+- 用 `` 包裹您的树,其中 `dehydratedState` 来自框架的 loader。如何获取 `dehydratedState` 也因框架而异。
+ - 这可以针对每个路由完成,也可以在应用程序顶部完成以避免样板代码,请参阅示例
+
+> 一个有趣的细节是实际上涉及**三个** `queryClient`。框架的 loader 是一种"预加载"阶段,发生在渲染之前,这个阶段有自己的 `queryClient` 进行预取。这个阶段的脱水结果被传递给**服务器渲染过程**和**客户端渲染过程**,它们各自有自己的 `queryClient`。这确保它们从相同的数据开始,因此可以返回相同的标记。
+
+> 服务器组件是另一种"预加载"阶段,也可以"预加载"(预渲染)React 组件树的部分。在[高级服务端渲染指南](./advanced-ssr.md)中了解更多。
+
+### 完整 Next.js pages router 示例
+
+> 有关 app router 的文档,请参阅[高级服务端渲染指南](./advanced-ssr.md)。
+
+初始设置:
+
+```tsx
+// _app.tsx
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
+
+export default function MyApp({ Component, pageProps }) {
+ const [queryClient] = React.useState(
+ () =>
+ new QueryClient({
+ defaultOptions: {
+ queries: {
+ // 使用 SSR 时,我们通常希望设置默认的 staleTime
+ // 大于 0,以避免在客户端立即重新获取
+ staleTime: 60 * 1000,
+ },
+ },
+ }),
+ )
+
+ return (
+
+
+
+ )
+}
+```
+
+在每个路由中:
+
+```tsx
+// pages/posts.tsx
+import {
+ dehydrate,
+ HydrationBoundary,
+ QueryClient,
+ useQuery,
+} from '@tanstack/react-query'
+
+// 也可以是 getServerSideProps
+export async function getStaticProps() {
+ const queryClient = new QueryClient()
+
+ await queryClient.prefetchQuery({
+ queryKey: ['posts'],
+ queryFn: getPosts,
+ })
+
+ return {
+ props: {
+ dehydratedState: dehydrate(queryClient),
+ },
+ }
+}
+
+function Posts() {
+ // 这个 useQuery 也可以发生在 的更深层子组件中,
+ // 数据将立即可用
+ const { data } = useQuery({ queryKey: ['posts'], queryFn: getPosts })
+
+ // 这个查询没有在服务器上预取,将在客户端才开始
+ // 获取,两种模式可以混合使用
+ const { data: commentsData } = useQuery({
+ queryKey: ['posts-comments'],
+ queryFn: getComments,
+ })
+
+ // ...
+}
+
+export default function PostsRoute({ dehydratedState }) {
+ return (
+
+
+
+ )
+}
+```
+
+### 完整 Remix 示例
+
+初始设置:
+
+```tsx
+// app/root.tsx
+import { Outlet } from '@remix-run/react'
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
+
+export default function MyApp() {
+ const [queryClient] = React.useState(
+ () =>
+ new QueryClient({
+ defaultOptions: {
+ queries: {
+ // 使用 SSR 时,我们通常希望设置默认的 staleTime
+ // 大于 0,以避免在客户端立即重新获取
+ staleTime: 60 * 1000,
+ },
+ },
+ }),
+ )
+
+ return (
+
+
+
+ )
+}
+```
+
+在每个路由中,注意也可以在嵌套路由中这样做:
+
+```tsx
+// app/routes/posts.tsx
+import { json } from '@remix-run/node'
+import {
+ dehydrate,
+ HydrationBoundary,
+ QueryClient,
+ useQuery,
+} from '@tanstack/react-query'
+
+export async function loader() {
+ const queryClient = new QueryClient()
+
+ await queryClient.prefetchQuery({
+ queryKey: ['posts'],
+ queryFn: getPosts,
+ })
+
+ return json({ dehydratedState: dehydrate(queryClient) })
+}
+
+function Posts() {
+ // 这个 useQuery 也可以发生在 的更深层子组件中,
+ // 数据将立即可用
+ const { data } = useQuery({ queryKey: ['posts'], queryFn: getPosts })
+
+ // 这个查询没有在服务器上预取,将在客户端才开始
+ // 获取,两种模式可以混合使用
+ const { data: commentsData } = useQuery({
+ queryKey: ['posts-comments'],
+ queryFn: getComments,
+ })
+
+ // ...
+}
+
+export default function PostsRoute() {
+ const { dehydratedState } = useLoaderData()
+ return (
+
+
+
+ )
+}
+```
+
+## 可选 - 移除样板代码
+
+在每个路由中都有这部分可能看起来有很多样板代码:
+
+```tsx
+export default function PostsRoute({ dehydratedState }) {
+ return (
+
+
+
+ )
+}
+```
+
+虽然这种方法没有问题,但如果您想摆脱这种样板代码,可以这样修改 Next.js 的设置:
+
+```tsx
+// _app.tsx
+import {
+ HydrationBoundary,
+ QueryClient,
+ QueryClientProvider,
+} from '@tanstack/react-query'
+
+export default function MyApp({ Component, pageProps }) {
+ const [queryClient] = React.useState(() => new QueryClient())
+
+ return (
+
+
+
+
+
+ )
+}
+
+// pages/posts.tsx
+// 移除带有 HydrationBoundary 的 PostsRoute,直接导出 Posts:
+export default function Posts() { ... }
+```
+
+对于 Remix,这稍微复杂一些,我们建议查看 [use-dehydrated-state](https://github.com/maplegrove-io/use-dehydrated-state) 包。
+
+## 预取依赖查询
+
+在预取指南中,我们学习了如何[预取依赖查询](./prefetching.md#dependent-queries--code-splitting),但我们如何在框架的 loader 中做到这一点?考虑以下代码,取自[依赖查询指南](./dependent-queries.md):
+
+```tsx
+// 获取用户
+const { data: user } = useQuery({
+ queryKey: ['user', email],
+ queryFn: getUserByEmail,
+})
+
+const userId = user?.id
+
+// 然后获取用户的项目
+const {
+ status,
+ fetchStatus,
+ data: projects,
+} = useQuery({
+ queryKey: ['projects', userId],
+ queryFn: getProjectsByUser,
+ // 查询直到 userId 存在才会执行
+ enabled: !!userId,
+})
+```
+
+我们如何预取这个以便它可以进行服务端渲染?这里有一个示例:
+
+```tsx
+// 对于 Remix,将此重命名为 loader
+export async function getServerSideProps() {
+ const queryClient = new QueryClient()
+
+ const user = await queryClient.fetchQuery({
+ queryKey: ['user', email],
+ queryFn: getUserByEmail,
+ })
+
+ if (user?.userId) {
+ await queryClient.prefetchQuery({
+ queryKey: ['projects', userId],
+ queryFn: getProjectsByUser,
+ })
+ }
+
+ // 对于 Remix:
+ // return json({ dehydratedState: dehydrate(queryClient) })
+ return { props: { dehydratedState: dehydrate(queryClient) } }
+}
+```
+
+当然,这可能会变得更复杂,但由于这些 loader 函数只是 JavaScript,您可以使用该语言的全部功能来构建您的逻辑。确保预取所有您希望进行服务端渲染的查询。
+
+## 错误处理
+
+React Query 默认为优雅降级策略。这意味着:
+
+- `queryClient.prefetchQuery(...)` 从不抛出错误
+- `dehydrate(...)` 只包含成功的查询,不包括失败的查询
+
+这将导致任何失败的查询在客户端重试,并且服务端渲染的输出将包括加载状态而不是完整内容。
+
+虽然这是一个很好的默认设置,但有时这并不是您想要的。当关键内容缺失时,您可能希望根据情况返回 404 或 500 状态码。对于这些情况,请改用 `queryClient.fetchQuery(...)`,它会在失败时抛出错误,让您以适当的方式处理事情。
+
+```tsx
+let result
+
+try {
+ result = await queryClient.fetchQuery(...)
+} catch (error) {
+ // 处理错误,参考您的框架文档
+}
+
+// 您可能还想检查并处理任何无效的 `result`
+```
+
+如果出于某种原因,您希望在脱水状态中包含失败的查询以避免重试,可以使用 `shouldDehydrateQuery` 选项覆盖默认函数并实现自己的逻辑:
+
+```tsx
+dehydrate(queryClient, {
+ shouldDehydrateQuery: (query) => {
+ // 这将包括所有查询,包括失败的查询,
+ // 但您也可以通过检查 `query` 实现自己的逻辑
+ return true
+ },
+})
+```
+
+## 序列化
+
+当在 Next.js 中执行 `return { props: { dehydratedState: dehydrate(queryClient) } }` 或在 Remix 中执行 `return json({ dehydratedState: dehydrate(queryClient) })` 时,发生的是 `queryClient` 的 `dehydratedState` 表示由框架序列化,以便可以嵌入到标记中并传输到客户端。
+
+默认情况下,这些框架仅支持返回可安全序列化/解析的内容,因此不支持 `undefined`、`Error`、`Date`、`Map`、`Set`、`BigInt`、`Infinity`、`NaN`、`-0`、正则表达式等。这也意味着您不能从查询中返回任何这些内容。如果返回这些值是您想要的,请查看 [superjson](https://github.com/blitz-js/superjson) 或类似的包。
+
+如果您使用自定义 SSR 设置,您需要自己处理这一步。您的第一反应可能是使用 `JSON.stringify(dehydratedState)`,但由于默认情况下这不会转义像 `` 这样的内容,这很容易导致
diff --git a/docs/zh-hans/framework/react/guides/suspense.md b/docs/zh-hans/framework/react/guides/suspense.md
new file mode 100644
index 00000000000..e1f5315fe40
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/suspense.md
@@ -0,0 +1,223 @@
+---
+source-updated-at: '2025-04-02T06:46:03.000Z'
+translation-updated-at: '2025-05-06T04:06:04.912Z'
+id: suspense
+title: Suspense
+---
+
+React Query 也可以与 React 的 Suspense for Data Fetching APIs 配合使用。为此,我们提供了专用的钩子:
+
+- [useSuspenseQuery](../reference/useSuspenseQuery.md)
+- [useSuspenseInfiniteQuery](../reference/useSuspenseInfiniteQuery.md)
+- [useSuspenseQueries](../reference/useSuspenseQueries.md)
+- 此外,你还可以使用 `useQuery().promise` 和 `React.use()`(实验性功能)
+
+当启用 suspense 模式时,不再需要 `status` 状态和 `error` 对象,它们会被 `React.Suspense` 组件(包括使用 `fallback` 属性和 React 错误边界来捕获错误)替代。请阅读 [重置错误边界](#resetting-error-boundaries) 并查看 [Suspense 示例](../examples/react/suspense) 了解如何设置 suspense 模式。
+
+如果你希望 mutations 将错误传播到最近的错误边界(类似于 queries),可以将 `throwOnError` 选项设置为 `true`。
+
+为 query 启用 suspense 模式:
+
+```tsx
+import { useSuspenseQuery } from '@tanstack/react-query'
+
+const { data } = useSuspenseQuery({ queryKey, queryFn })
+```
+
+这在 TypeScript 中运行良好,因为 `data` 保证已定义(错误和加载状态由 Suspense 和 ErrorBoundaries 处理)。
+
+另一方面,因此你不能有条件地启用/禁用 Query。对于依赖的 Queries 来说,这通常不是必需的,因为使用 suspense 时,组件内的所有 Queries 会按顺序获取。
+
+这种 Query 也不存在 `placeholderData`。为了防止 UI 在更新期间被 fallback 替换,请将更改 QueryKey 的更新包装在 [startTransition](https://react.dev/reference/react/Suspense#preventing-unwanted-fallbacks) 中。
+
+### throwOnError 默认值
+
+默认情况下,并非所有错误都会抛出到最近的错误边界——我们只会在没有其他数据可显示时抛出错误。这意味着如果 Query 曾经在缓存中成功获取过数据,即使数据是 `stale` 的,组件也会渲染。因此,`throwOnError` 的默认值为:
+
+```
+throwOnError: (error, query) => typeof query.state.data === 'undefined'
+```
+
+由于你不能更改 `throwOnError`(因为这可能导致 `data` 变为 `undefined`),如果你希望所有错误都由错误边界处理,必须手动抛出错误:
+
+```tsx
+import { useSuspenseQuery } from '@tanstack/react-query'
+
+const { data, error, isFetching } = useSuspenseQuery({ queryKey, queryFn })
+
+if (error && !isFetching) {
+ throw error
+}
+
+// 继续渲染数据
+```
+
+## 重置错误边界
+
+无论你在 queries 中使用的是 **suspense** 还是 **throwOnError**,都需要一种方式让 queries 知道在发生错误后重新渲染时你想重试。
+
+Query 错误可以通过 `QueryErrorResetBoundary` 组件或 `useQueryErrorResetBoundary` 钩子重置。
+
+使用组件时,它会重置组件边界内的所有 query 错误:
+
+```tsx
+import { QueryErrorResetBoundary } from '@tanstack/react-query'
+import { ErrorBoundary } from 'react-error-boundary'
+
+const App = () => (
+
+ {({ reset }) => (
+ (
+
+ 发生错误!
+ resetErrorBoundary()}>重试
+
+ )}
+ >
+
+
+ )}
+
+)
+```
+
+使用钩子时,它会重置最近的 `QueryErrorResetBoundary` 内的所有 query 错误。如果没有定义边界,则会全局重置:
+
+```tsx
+import { useQueryErrorResetBoundary } from '@tanstack/react-query'
+import { ErrorBoundary } from 'react-error-boundary'
+
+const App = () => {
+ const { reset } = useQueryErrorResetBoundary()
+ return (
+ (
+
+ 发生错误!
+ resetErrorBoundary()}>重试
+
+ )}
+ >
+
+
+ )
+}
+```
+
+## 渲染时获取 vs 边渲染边获取
+
+默认情况下,React Query 在 `suspense` 模式下作为 **渲染时获取 (Fetch-on-render)** 解决方案运行良好,无需额外配置。这意味着当你的组件尝试挂载时,它们会触发 query 获取并暂停,但只有在你导入并挂载它们之后才会发生。如果你想更进一步,实现 **边渲染边获取 (Render-as-you-fetch)** 模型,我们建议在路由回调和/或用户交互事件上实现 [预取 (Prefetching)](./prefetching.md),以便在挂载之前开始加载 queries,甚至在你开始导入或挂载它们的父组件之前。
+
+## 服务端 Suspense 与流式渲染
+
+如果你使用 `NextJs`,可以使用我们的 **实验性** 集成来实现服务端 Suspense:`@tanstack/react-query-next-experimental`。这个包允许你在服务端(在客户端组件中)获取数据,只需在组件中调用 `useSuspenseQuery`。结果会随着 SuspenseBoundaries 的解析从服务端流式传输到客户端。
+
+要实现这一点,请将你的应用包装在 `ReactQueryStreamedHydration` 组件中:
+
+```tsx
+// app/providers.tsx
+'use client'
+
+import {
+ isServer,
+ QueryClient,
+ QueryClientProvider,
+} from '@tanstack/react-query'
+import * as React from 'react'
+import { ReactQueryStreamedHydration } from '@tanstack/react-query-next-experimental'
+
+function makeQueryClient() {
+ return new QueryClient({
+ defaultOptions: {
+ queries: {
+ // 使用 SSR 时,通常希望将默认的 staleTime 设置为
+ // 大于 0 的值,以避免在客户端立即重新获取
+ staleTime: 60 * 1000,
+ },
+ },
+ })
+}
+
+let browserQueryClient: QueryClient | undefined = undefined
+
+function getQueryClient() {
+ if (isServer) {
+ // 服务端:始终创建一个新的 query client
+ return makeQueryClient()
+ } else {
+ // 浏览器:如果没有 query client,则创建一个新的
+ // 这非常重要,这样在初始渲染期间 React 暂停时不会重新创建 client
+ // 如果我们在创建 query client 下方有 suspense 边界,则可能不需要这样做
+ if (!browserQueryClient) browserQueryClient = makeQueryClient()
+ return browserQueryClient
+ }
+}
+
+export function Providers(props: { children: React.ReactNode }) {
+ // 注意:如果在初始化 query client 时没有 suspense 边界,
+ // 避免使用 useState,因为 React 会在初始渲染暂停时丢弃 client
+ const queryClient = getQueryClient()
+
+ return (
+
+
+ {props.children}
+
+
+ )
+}
+```
+
+更多信息,请查看 [NextJs Suspense 流式渲染示例](../examples/react/nextjs-suspense-streaming) 和 [高级渲染与注水 (Advanced Rendering & Hydration)](./advanced-ssr.md) 指南。
+
+## 使用 `useQuery().promise` 和 `React.use()`(实验性功能)
+
+> 要启用此功能,你需要在创建 `QueryClient` 时将 `experimental_prefetchInRender` 选项设置为 `true`
+
+**示例代码:**
+
+```tsx
+const queryClient = new QueryClient({
+ defaultOptions: {
+ queries: {
+ experimental_prefetchInRender: true,
+ },
+ },
+})
+```
+
+**用法:**
+
+```tsx
+import React from 'react'
+import { useQuery } from '@tanstack/react-query'
+import { fetchTodos, type Todo } from './api'
+
+function TodoList({ query }: { query: UseQueryResult }) {
+ const data = React.use(query.promise)
+
+ return (
+
+ {data.map((todo) => (
+ {todo.title}
+ ))}
+
+ )
+}
+
+export function App() {
+ const query = useQuery({ queryKey: ['todos'], queryFn: fetchTodos })
+
+ return (
+ <>
+ Todos
+ Loading...}>
+
+
+ >
+ )
+}
+```
diff --git a/docs/zh-hans/framework/react/guides/testing.md b/docs/zh-hans/framework/react/guides/testing.md
new file mode 100644
index 00000000000..f680afdd986
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/testing.md
@@ -0,0 +1,169 @@
+---
+source-updated-at: '2025-03-24T10:00:44.000Z'
+translation-updated-at: '2025-05-06T04:03:34.392Z'
+id: testing
+title: 测试
+---
+
+React Query 通过钩子(hooks)机制工作——无论是我们提供的钩子还是围绕它们封装的自定义钩子。
+
+在 React 17 或更早版本中,可以使用 [React Hooks Testing Library](https://react-hooks-testing-library.com/) 库为这些自定义钩子编写单元测试。
+
+通过以下命令安装:
+
+```sh
+npm install @testing-library/react-hooks react-test-renderer --save-dev
+```
+
+(`react-test-renderer` 库是 `@testing-library/react-hooks` 的 peer 依赖项,其版本需与当前使用的 React 版本对应。)
+
+_注意_:在 React 18 或更高版本中,`renderHook` 可直接通过 `@testing-library/react` 包使用,不再需要 `@testing-library/react-hooks`。
+
+## 第一个测试
+
+安装完成后,可以编写一个简单测试。假设有以下自定义钩子:
+
+```tsx
+export function useCustomHook() {
+ return useQuery({ queryKey: ['customHook'], queryFn: () => 'Hello' })
+}
+```
+
+对应的测试代码如下:
+
+```tsx
+import { renderHook, waitFor } from '@testing-library/react'
+
+const queryClient = new QueryClient()
+const wrapper = ({ children }) => (
+ {children}
+)
+
+const { result } = renderHook(() => useCustomHook(), { wrapper })
+
+await waitFor(() => expect(result.current.isSuccess).toBe(true))
+
+expect(result.current.data).toEqual('Hello')
+```
+
+注意我们提供了一个自定义包装器(wrapper),用于构建 `QueryClient` 和 `QueryClientProvider`。这确保了测试与其他测试完全隔离。
+
+虽然可以全局只编写一次包装器,但需确保每次测试前清空 `QueryClient`,且测试不能并行运行,否则会相互影响结果。
+
+## 关闭重试机制
+
+库默认会进行三次指数退避重试,因此测试错误查询时可能导致超时。最简单的方式是通过 `QueryClientProvider` 全局关闭重试。扩展上述示例:
+
+```tsx
+const queryClient = new QueryClient({
+ defaultOptions: {
+ queries: {
+ // ✅ 关闭重试
+ retry: false,
+ },
+ },
+})
+const wrapper = ({ children }) => (
+ {children}
+)
+```
+
+这会设置组件树中所有查询的默认行为为“不重试”。需注意,仅当实际 `useQuery` 未显式设置重试次数时此配置生效。若某查询明确要求重试5次,该设置仍会优先于全局默认值。
+
+## 在 Jest 中设置 gcTime 为 Infinity
+
+如果使用 Jest,可将 `gcTime` 设为 `Infinity` 以避免出现“Jest 在测试完成后未及时退出”的错误。这是服务端的默认行为,仅当显式设置 `gcTime` 时才需要调整。
+
+## 测试网络请求
+
+React Query 的主要用途是缓存网络请求,因此验证代码是否发起正确的网络请求至关重要。
+
+测试方法有多种,本例使用 [nock](https://www.npmjs.com/package/nock)。假设有以下自定义钩子:
+
+```tsx
+function useFetchData() {
+ return useQuery({
+ queryKey: ['fetchData'],
+ queryFn: () => request('/api/data'),
+ })
+}
+```
+
+测试代码如下:
+
+```tsx
+const queryClient = new QueryClient()
+const wrapper = ({ children }) => (
+ {children}
+)
+
+const expectation = nock('http://example.com').get('/api/data').reply(200, {
+ answer: 42,
+})
+
+const { result } = renderHook(() => useFetchData(), { wrapper })
+
+await waitFor(() => expect(result.current.isSuccess).toBe(true))
+
+expect(result.current.data).toEqual({ answer: 42 })
+```
+
+这里使用 `waitFor` 等待查询状态变为成功,确保钩子已完成处理并返回正确数据。_注意_:在 React 18 中,`waitFor` 的语义有所变化。
+
+## 测试加载更多/无限滚动
+
+首先模拟 API 响应:
+
+```tsx
+function generateMockedResponse(page) {
+ return {
+ page: page,
+ items: [...]
+ }
+}
+```
+
+然后通过 `nock` 配置基于页码区分响应,利用 `uri` 实现动态匹配(如 `"/?page=1"` 或 `"/?page=2"`):
+
+```tsx
+const expectation = nock('http://example.com')
+ .persist()
+ .query(true)
+ .get('/api/data')
+ .reply(200, (uri) => {
+ const url = new URL(`http://example.com${uri}`)
+ const { page } = Object.fromEntries(url.searchParams)
+ return generateMockedResponse(page)
+ })
+```
+
+(注意 `.persist()`,因为会多次调用同一接口)
+
+测试时关键点是等待数据断言通过:
+
+```tsx
+const { result } = renderHook(() => useInfiniteQueryCustomHook(), {
+ wrapper,
+})
+
+await waitFor(() => expect(result.current.isSuccess).toBe(true))
+
+expect(result.current.data.pages).toStrictEqual(generateMockedResponse(1))
+
+result.current.fetchNextPage()
+
+await waitFor(() =>
+ expect(result.current.data.pages).toStrictEqual([
+ ...generateMockedResponse(1),
+ ...generateMockedResponse(2),
+ ]),
+)
+
+expectation.done()
+```
+
+_注意_:React 18 中 `waitFor` 的语义变化同上文所述。
+
+## 延伸阅读
+
+更多技巧及使用 `mock-service-worker` 的替代方案,可参考社区资源中的 [Testing React Query](../community/tkdodos-blog.md#5-testing-react-query)。
diff --git a/docs/zh-hans/framework/react/guides/updates-from-mutation-responses.md b/docs/zh-hans/framework/react/guides/updates-from-mutation-responses.md
new file mode 100644
index 00000000000..11880b8cd03
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/updates-from-mutation-responses.md
@@ -0,0 +1,84 @@
+---
+source-updated-at: '2025-03-18T08:45:11.000Z'
+translation-updated-at: '2025-05-06T04:02:08.804Z'
+id: updates-from-mutation-responses
+title: 从变更响应中更新
+---
+
+处理那些**更新**服务器上对象的变更(mutations)时,变更响应中通常会自动返回新对象。与其重新获取该条目的查询并浪费网络请求去获取已有的数据,不如利用变更函数返回的对象,通过 [Query Client 的 `setQueryData`](../../../reference/QueryClient.md#queryclientsetquerydata) 方法立即用新数据更新现有查询:
+
+[//]: # '示例'
+
+```tsx
+const queryClient = useQueryClient()
+
+const mutation = useMutation({
+ mutationFn: editTodo,
+ onSuccess: (data) => {
+ queryClient.setQueryData(['todo', { id: 5 }], data)
+ },
+})
+
+mutation.mutate({
+ id: 5,
+ name: 'Do the laundry',
+})
+
+// 下面的查询会通过成功变更的响应自动更新
+const { status, data, error } = useQuery({
+ queryKey: ['todo', { id: 5 }],
+ queryFn: fetchTodoById,
+})
+```
+
+[//]: # '示例'
+
+若想将 `onSuccess` 逻辑封装成可复用的变更,可以创建如下自定义钩子:
+
+[//]: # '示例2'
+
+```tsx
+const useMutateTodo = () => {
+ const queryClient = useQueryClient()
+
+ return useMutation({
+ mutationFn: editTodo,
+ // 注意第二个参数是 `mutate` 函数接收的变量对象
+ onSuccess: (data, variables) => {
+ queryClient.setQueryData(['todo', { id: variables.id }], data)
+ },
+ })
+}
+```
+
+[//]: # '示例2'
+
+## 不可变性
+
+通过 `setQueryData` 更新必须遵循**不可变**原则。**禁止**直接修改从缓存中获取的数据并原地写入缓存。虽然初期可能生效,但会导致难以察觉的潜在错误。
+
+[//]: # '示例3'
+
+```tsx
+queryClient.setQueryData(['posts', { id }], (oldData) => {
+ if (oldData) {
+ // ❌ 切勿如此操作
+ oldData.title = 'my new post title'
+ }
+ return oldData
+})
+
+queryClient.setQueryData(
+ ['posts', { id }],
+ // ✅ 这才是正确方式
+ (oldData) =>
+ oldData
+ ? {
+ ...oldData,
+ title: 'my new post title',
+ }
+ : oldData,
+)
+```
+
+[//]: # '示例3'
diff --git a/docs/zh-hans/framework/react/guides/window-focus-refetching.md b/docs/zh-hans/framework/react/guides/window-focus-refetching.md
new file mode 100644
index 00000000000..717dedb686c
--- /dev/null
+++ b/docs/zh-hans/framework/react/guides/window-focus-refetching.md
@@ -0,0 +1,107 @@
+---
+source-updated-at: '2024-05-10T12:03:22.000Z'
+translation-updated-at: '2025-05-06T04:02:39.658Z'
+id: window-focus-refetching
+title: 窗口焦点重新获取
+---
+
+如果用户离开应用后返回,且查询数据已过时,**TanStack Query 会自动在后台为你请求最新数据**。你可以通过 `refetchOnWindowFocus` 选项全局或按查询禁用此行为:
+
+#### 全局禁用
+
+[//]: # 'Example'
+
+```tsx
+//
+const queryClient = new QueryClient({
+ defaultOptions: {
+ queries: {
+ refetchOnWindowFocus: false, // 默认值: true
+ },
+ },
+})
+
+function App() {
+ return ...
+}
+```
+
+[//]: # 'Example'
+
+#### 按查询禁用
+
+[//]: # 'Example2'
+
+```tsx
+useQuery({
+ queryKey: ['todos'],
+ queryFn: fetchTodos,
+ refetchOnWindowFocus: false,
+})
+```
+
+[//]: # 'Example2'
+
+## 自定义窗口聚焦事件
+
+在极少数情况下,你可能希望自行管理触发 TanStack Query 重新验证的窗口聚焦事件。为此,TanStack Query 提供了 `focusManager.setEventListener` 函数,该函数会提供窗口聚焦时应触发的回调,并允许你设置自定义事件。调用 `focusManager.setEventListener` 时,先前设置的事件处理器会被移除(大多数情况下是默认处理器),并替换为你的新处理器。以下是默认处理器的实现示例:
+
+[//]: # 'Example3'
+
+```tsx
+focusManager.setEventListener((handleFocus) => {
+ // 监听 visibilitychange 事件
+ if (typeof window !== 'undefined' && window.addEventListener) {
+ const visibilitychangeHandler = () => {
+ handleFocus(document.visibilityState === 'visible')
+ }
+ window.addEventListener('visibilitychange', visibilitychangeHandler, false)
+ return () => {
+ // 确保在新处理器设置时取消订阅
+ window.removeEventListener('visibilitychange', visibilitychangeHandler)
+ }
+ }
+})
+```
+
+[//]: # 'Example3'
+[//]: # 'ReactNative'
+
+## 在 React Native 中管理聚焦状态
+
+不同于在 `window` 上监听事件,React Native 通过 [`AppState` 模块](https://reactnative.dev/docs/appstate#app-states) 提供聚焦信息。你可以使用 `AppState` 的 "change" 事件在应用状态变为 "active" 时触发更新:
+
+```tsx
+import { AppState } from 'react-native'
+import { focusManager } from '@tanstack/react-query'
+
+function onAppStateChange(status: AppStateStatus) {
+ if (Platform.OS !== 'web') {
+ focusManager.setFocused(status === 'active')
+ }
+}
+
+useEffect(() => {
+ const subscription = AppState.addEventListener('change', onAppStateChange)
+
+ return () => subscription.remove()
+}, [])
+```
+
+[//]: # 'ReactNative'
+
+## 管理聚焦状态
+
+[//]: # 'Example4'
+
+```tsx
+import { focusManager } from '@tanstack/react-query'
+
+// 覆盖默认聚焦状态
+focusManager.setFocused(true)
+
+// 回退到默认聚焦检查
+focusManager.setFocused(undefined)
+```
+
+[//]: # 'Example4'
diff --git a/docs/zh-hans/framework/react/installation.md b/docs/zh-hans/framework/react/installation.md
new file mode 100644
index 00000000000..b273de6b612
--- /dev/null
+++ b/docs/zh-hans/framework/react/installation.md
@@ -0,0 +1,93 @@
+---
+source-updated-at: '2025-03-18T08:45:11.000Z'
+translation-updated-at: '2025-05-06T04:26:26.668Z'
+id: installation
+title: 安装
+---
+
+# 安装
+
+您可以通过 [NPM](https://npmjs.com/) 安装 React Query,或者通过 [ESM.sh](https://esm.sh/) 使用传统的 `
+```
+
+> 您可以在 [这里](https://react.dev/reference/react/createElement#creating-an-element-without-jsx) 找到不使用 JSX 来使用 React 的说明。
+
+### 环境要求
+
+React Query 针对现代浏览器进行了优化,兼容以下浏览器配置:
+
+```
+Chrome >= 91
+Firefox >= 90
+Edge >= 91
+Safari >= 15
+iOS >= 15
+Opera >= 77
+```
+
+> 根据您的环境,可能需要添加 polyfill。如果需要支持旧版浏览器,您需要自行转译 `node_modules` 中的库文件。
+
+### 推荐配置
+
+建议同时使用我们的 [ESLint Plugin Query](../../eslint/eslint-plugin-query.md) 来帮助您在编码时发现错误和不一致。可通过以下命令安装:
+
+```bash
+npm i -D @tanstack/eslint-plugin-query
+```
+
+或
+
+```bash
+pnpm add -D @tanstack/eslint-plugin-query
+```
+
+或
+
+```bash
+yarn add -D @tanstack/eslint-plugin-query
+```
+
+或
+
+```bash
+bun add -D @tanstack/eslint-plugin-query
+```
diff --git a/docs/zh-hans/framework/react/overview.md b/docs/zh-hans/framework/react/overview.md
new file mode 100644
index 00000000000..b55fa1f2ed4
--- /dev/null
+++ b/docs/zh-hans/framework/react/overview.md
@@ -0,0 +1,103 @@
+---
+source-updated-at: '2025-04-02T06:45:29.000Z'
+translation-updated-at: '2025-05-06T04:32:50.321Z'
+id: overview
+title: 概述
+---
+
+TanStack Query(前身为 React Query)常被描述为 Web 应用程序中缺失的数据获取库,但更专业地说,它能让 **获取、缓存、同步和更新服务端状态 (server state)** 在你的 Web 应用中变得轻而易举。
+
+## 动机
+
+大多数核心 Web 框架 **并未** 提供一种全面的数据获取或更新方式。因此,开发者最终要么构建封装了严格数据获取理念的元框架 (meta-frameworks),要么发明自己的数据获取方法。这通常意味着拼凑基于组件的状态和副作用,或使用更通用的状态管理库来存储和提供整个应用中的异步数据。
+
+虽然大多数传统状态管理库非常适合处理客户端状态 (client state),但它们 **并不擅长处理异步或服务端状态 (server state)**。这是因为 **服务端状态完全不同**。首先,服务端状态:
+
+- 持久化存储在远程位置,你可能无法控制或拥有该位置
+- 需要通过异步 API 进行获取和更新
+- 意味着共享所有权,可能被其他人更改而无需你知晓
+- 如果不加注意,可能会在你的应用中变得“过时 (out of date)”
+
+一旦你理解了应用中服务端状态的本质,**更多挑战会接踵而至**,例如:
+
+- 缓存...(可能是编程中最难的事情)
+- 将针对同一数据的多个请求去重 (deduping) 为单个请求
+- 在后台更新“过时”数据
+- 判断数据何时“过时”
+- 尽可能快地反映数据更新
+- 分页 (pagination) 和懒加载 (lazy loading) 等性能优化
+- 管理服务端状态的内存和垃圾回收 (garbage collection)
+- 通过结构共享 (structural sharing) 记忆化 (memoizing) 查询结果
+
+如果你没有被这个清单吓到,那一定意味着你已经解决了所有服务端状态问题,值得嘉奖。然而,如果你像绝大多数人一样,那么你要么尚未解决全部或大部分挑战,而我们才刚刚触及皮毛!
+
+TanStack Query 无疑是管理服务端状态的 **最佳** 库之一。它 **开箱即用、零配置**,并且可以随着应用的增长按需定制。
+
+TanStack Query 能让你战胜并克服 **服务端状态** 的棘手挑战,在数据控制你之前掌控你的应用数据。
+
+从技术角度来说,TanStack Query 可能会:
+
+- 帮助你从应用中移除 **大量** 复杂且难以理解的代码,仅用寥寥几行 TanStack Query 逻辑替代
+- 使你的应用更易维护,更容易构建新功能,而无需担心接入新的服务端状态数据源
+- 通过让你的应用感觉比以往更快、响应更迅速,直接影响终端用户的体验
+- 可能帮助你节省带宽并提升内存性能
+
+[//]: # 'Example'
+
+## 说够了,直接看代码吧!
+
+在下面的示例中,你可以看到 TanStack Query 最基本、最简单的形式,用于获取 TanStack Query GitHub 项目本身的统计信息:
+
+[在 StackBlitz 中打开](https://stackblitz.com/github/TanStack/query/tree/main/examples/react/simple)
+
+```tsx
+import {
+ QueryClient,
+ QueryClientProvider,
+ useQuery,
+} from '@tanstack/react-query'
+
+const queryClient = new QueryClient()
+
+export default function App() {
+ return (
+
+
+
+ )
+}
+
+function Example() {
+ const { isPending, error, data } = useQuery({
+ queryKey: ['repoData'],
+ queryFn: () =>
+ fetch('https://api.github.com/repos/TanStack/query').then((res) =>
+ res.json(),
+ ),
+ })
+
+ if (isPending) return 'Loading...'
+
+ if (error) return 'An error has occurred: ' + error.message
+
+ return (
+
+
{data.name}
+
{data.description}
+
👀 {data.subscribers_count} {' '}
+
✨ {data.stargazers_count} {' '}
+
🍴 {data.forks_count}
+
+ )
+}
+```
+
+[//]: # 'Example'
+[//]: # 'Materials'
+
+## 你说服我了,接下来呢?
+
+- 考虑参加官方的 [TanStack Query 课程](https://query.gg?s=tanstack)(或为整个团队购买!)
+- 通过我们极其详尽的 [入门指南](./installation.md) 和 [API 参考](./reference/useQuery.md),按照自己的节奏学习 TanStack Query
+
+[//]: # 'Materials'
diff --git a/docs/zh-hans/framework/react/plugins/broadcastQueryClient.md b/docs/zh-hans/framework/react/plugins/broadcastQueryClient.md
new file mode 100644
index 00000000000..b64710b8769
--- /dev/null
+++ b/docs/zh-hans/framework/react/plugins/broadcastQueryClient.md
@@ -0,0 +1,62 @@
+---
+source-updated-at: '2024-12-16T15:14:41.000Z'
+translation-updated-at: '2025-05-06T04:46:07.089Z'
+id: broadcastQueryClient
+title: broadcastQueryClient (实验性)
+---
+
+> 重要提示:该工具目前处于实验阶段。这意味着在次要版本和补丁版本中都可能出现破坏性变更。使用时需自行承担风险。如果您选择在生产环境中依赖此实验阶段的功能,请将版本锁定到具体的补丁版本以避免意外中断。
+
+`broadcastQueryClient` 是一个用于在同源浏览器标签页/窗口之间广播和同步 queryClient 状态的工具。
+
+## 安装
+
+该工具作为独立包提供,可通过 `'@tanstack/query-broadcast-client-experimental'` 导入。
+
+## 使用方式
+
+导入 `broadcastQueryClient` 函数,传入您的 `QueryClient` 实例,并可选地设置 `broadcastChannel`。
+
+```tsx
+import { broadcastQueryClient } from '@tanstack/query-broadcast-client-experimental'
+
+const queryClient = new QueryClient()
+
+broadcastQueryClient({
+ queryClient,
+ broadcastChannel: 'my-app',
+})
+```
+
+## API
+
+### `broadcastQueryClient`
+
+向该函数传入一个 `QueryClient` 实例,并可选择性地传入 `broadcastChannel`。
+
+```tsx
+broadcastQueryClient({ queryClient, broadcastChannel })
+```
+
+### `Options`
+
+选项对象:
+
+```tsx
+interface BroadcastQueryClientOptions {
+ /** 需要同步的 QueryClient */
+ queryClient: QueryClient
+ /** 用于在标签页和窗口之间通信的唯一频道名称 */
+ broadcastChannel?: string
+ /** BroadcastChannel API 的选项 */
+ options?: BroadcastChannelOptions
+}
+```
+
+默认选项为:
+
+```tsx
+{
+ broadcastChannel = 'tanstack-query',
+}
+```
diff --git a/docs/zh-hans/framework/react/plugins/createAsyncStoragePersister.md b/docs/zh-hans/framework/react/plugins/createAsyncStoragePersister.md
new file mode 100644
index 00000000000..ac3b27fc0c6
--- /dev/null
+++ b/docs/zh-hans/framework/react/plugins/createAsyncStoragePersister.md
@@ -0,0 +1,120 @@
+---
+source-updated-at: '2025-03-18T08:45:11.000Z'
+translation-updated-at: '2025-05-06T04:46:58.579Z'
+id: createAsyncStoragePersister
+title: createAsyncStoragePersister
+---
+
+## 安装
+
+该工具作为一个独立包提供,可通过 `'@tanstack/query-async-storage-persister'` 导入使用。
+
+```bash
+npm install @tanstack/query-async-storage-persister @tanstack/react-query-persist-client
+```
+
+或
+
+```bash
+pnpm add @tanstack/query-async-storage-persister @tanstack/react-query-persist-client
+```
+
+或
+
+```bash
+yarn add @tanstack/query-async-storage-persister @tanstack/react-query-persist-client
+```
+
+或
+
+```bash
+bun add @tanstack/query-async-storage-persister @tanstack/react-query-persist-client
+```
+
+## 使用方式
+
+- 导入 `createAsyncStoragePersister` 函数
+- 创建一个新的 asyncStoragePersister
+ - 可传入任何符合 `AsyncStorage` 接口的 `storage` 对象 - 以下示例使用 React Native 的 async-storage
+- 使用 [`PersistQueryClientProvider`](./persistQueryClient.md#persistqueryclientprovider) 组件包裹你的应用
+
+```tsx
+import AsyncStorage from '@react-native-async-storage/async-storage'
+import { QueryClient } from '@tanstack/react-query'
+import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client'
+import { createAsyncStoragePersister } from '@tanstack/query-async-storage-persister'
+
+const queryClient = new QueryClient({
+ defaultOptions: {
+ queries: {
+ gcTime: 1000 * 60 * 60 * 24, // 24 小时
+ },
+ },
+})
+
+const asyncStoragePersister = createAsyncStoragePersister({
+ storage: AsyncStorage,
+})
+
+const Root = () => (
+
+
+
+)
+
+export default Root
+```
+
+## 重试机制
+
+重试逻辑与 [SyncStoragePersister](./createSyncStoragePersister.md) 相同,但支持异步操作。你也可以使用所有预定义的重试处理器。
+
+## API 接口
+
+### `createAsyncStoragePersister`
+
+调用此函数创建 asyncStoragePersister,后续可与 `persistQueryClient` 配合使用。
+
+```tsx
+createAsyncStoragePersister(options: CreateAsyncStoragePersisterOptions)
+```
+
+### 配置选项
+
+```tsx
+interface CreateAsyncStoragePersisterOptions {
+ /** 用于缓存存取操作的存储客户端 */
+ storage: AsyncStorage | undefined | null
+ /** 本地存储缓存时使用的键名 */
+ key?: string
+ /** 为避免频繁写入本地存储,
+ * 可设置节流时间(毫秒)来控制缓存写入频率 */
+ throttleTime?: number
+ /** 数据序列化方法 */
+ serialize?: (client: PersistedClient) => string
+ /** 数据反序列化方法 */
+ deserialize?: (cachedString: string) => PersistedClient
+ /** 错误时的持久化重试策略 **/
+ retry?: AsyncPersistRetryer
+}
+
+interface AsyncStorage {
+ getItem: (key: string) => Promise
+ setItem: (key: string, value: string) => Promise
+ removeItem: (key: string) => Promise
+}
+```
+
+默认配置为:
+
+```tsx
+{
+ key = `REACT_QUERY_OFFLINE_CACHE`,
+ throttleTime = 1000,
+ serialize = JSON.stringify,
+ deserialize = JSON.parse,
+}
+```
diff --git a/docs/zh-hans/framework/react/plugins/createPersister.md b/docs/zh-hans/framework/react/plugins/createPersister.md
new file mode 100644
index 00000000000..4de107141ce
--- /dev/null
+++ b/docs/zh-hans/framework/react/plugins/createPersister.md
@@ -0,0 +1,136 @@
+---
+source-updated-at: '2024-02-25T09:15:32.000Z'
+translation-updated-at: '2025-05-06T04:45:26.192Z'
+id: createPersister
+title: createPersister (实验性)
+---
+
+## 安装
+
+该工具作为一个独立包提供,可通过 `'@tanstack/query-persist-client-core'` 导入使用。
+
+```bash
+npm install @tanstack/query-persist-client-core
+```
+
+或
+
+```bash
+pnpm add @tanstack/query-persist-client-core
+```
+
+或
+
+```bash
+yarn add @tanstack/query-persist-client-core
+```
+
+或
+
+```bash
+bun add @tanstack/query-persist-client-core
+```
+
+> 注意:此工具也包含在 `@tanstack/react-query-persist-client` 包中,因此如果已使用该包则无需单独安装。
+
+## 使用方式
+
+- 导入 `experimental_createPersister` 函数
+- 创建一个新的 `experimental_createPersister`
+ - 可传入任何符合 `AsyncStorage` 或 `Storage` 接口的 `storage` —— 以下示例使用 React Native 的 async-storage
+- 将该 `persister` 作为选项传递给 Query。可通过两种方式实现:传递给 `QueryClient` 的 `defaultOptions`,或传递给任意 `useQuery` 钩子实例
+ - 若将 `persister` 作为 `defaultOptions` 传递,所有查询将被持久化到提供的 `storage` 中。还可通过传递 `filters` 进一步缩小范围。与 `persistClient` 插件不同,此方式不会将整个 query client 作为单个项目持久化,而是分别持久化每个查询。查询哈希值将作为键名使用
+ - 若将 `persister` 提供给单个 `useQuery` 钩子,则仅该查询会被持久化
+
+这种方式无需存储整个 `QueryClient`,而是可选择应用中值得持久化的内容。每个查询都是延迟恢复(当查询首次使用时)和持久化(在每次 `queryFn` 运行后)的,因此无需节流处理。恢复查询后也会遵循 `staleTime` 设置,因此若数据被视为 `stale`,将在恢复后立即重新获取;若数据为 `fresh` 状态,则不会运行 `queryFn`。
+
+从内存中垃圾回收查询**不会**影响持久化数据。这意味着可以缩短查询在内存中的保留时间以提高**内存效率**。当下次使用时,它们会直接从持久化存储中恢复。
+
+```tsx
+import AsyncStorage from '@react-native-async-storage/async-storage'
+import { QueryClient } from '@tanstack/react-query'
+import { experimental_createPersister } from '@tanstack/query-persist-client-core'
+
+const queryClient = new QueryClient({
+ defaultOptions: {
+ queries: {
+ gcTime: 1000 * 30, // 30 秒
+ persister: experimental_createPersister({
+ storage: AsyncStorage,
+ maxAge: 1000 * 60 * 60 * 12, // 12 小时
+ }),
+ },
+ },
+})
+```
+
+### 适配的默认值
+
+`createPersister` 插件在技术上封装了 `queryFn`,因此若 `queryFn` 未运行则不会恢复。在此意义上,它充当了查询与网络之间的缓存层。因此,当使用 persister 时,`networkMode` 默认设为 `'offlineFirst'`,以便即使没有网络连接也能从持久化存储中恢复。
+
+## API
+
+### `experimental_createPersister`
+
+```tsx
+experimental_createPersister(options: StoragePersisterOptions)
+```
+
+#### `选项`
+
+```tsx
+export interface StoragePersisterOptions {
+ /** 用于设置和检索缓存项的存储客户端
+ * 对于 SSR 请传入 `undefined`
+ */
+ storage: AsyncStorage | Storage | undefined | null
+ /**
+ * 如何将数据序列化存储
+ * @默认值 `JSON.stringify`
+ */
+ serialize?: (persistedQuery: PersistedQuery) => string
+ /**
+ * 如何从存储中反序列化数据
+ * @默认值 `JSON.parse`
+ */
+ deserialize?: (cachedString: string) => PersistedQuery
+ /**
+ * 用于强制使现有缓存失效的唯一字符串
+ * 若缓存不共享相同的破坏字符串则会被视为无效
+ */
+ buster?: string
+ /**
+ * 缓存允许的最大存活时间(毫秒)
+ * 若发现持久化缓存超过此时长
+ * 将被丢弃
+ * @默认值 24 小时
+ */
+ maxAge?: number
+ /**
+ * 存储键的前缀
+ * 存储键由前缀和查询哈希组成,格式为 `prefix-queryHash`
+ */
+ prefix?: string
+ /**
+ * 用于筛选哪些查询应被持久化的过滤器
+ */
+ filters?: QueryFilters
+}
+
+interface AsyncStorage {
+ getItem: (key: string) => Promise
+ setItem: (key: string, value: string) => Promise
+ removeItem: (key: string) => Promise
+}
+```
+
+默认选项为:
+
+```tsx
+{
+ prefix = 'tanstack-query',
+ maxAge = 1000 * 60 * 60 * 24,
+ serialize = JSON.stringify,
+ deserialize = JSON.parse,
+}
+```
diff --git a/docs/zh-hans/framework/react/plugins/createSyncStoragePersister.md b/docs/zh-hans/framework/react/plugins/createSyncStoragePersister.md
new file mode 100644
index 00000000000..69104a8a78b
--- /dev/null
+++ b/docs/zh-hans/framework/react/plugins/createSyncStoragePersister.md
@@ -0,0 +1,156 @@
+---
+source-updated-at: '2025-03-18T08:45:11.000Z'
+translation-updated-at: '2025-05-06T04:44:34.356Z'
+id: createSyncStoragePersister
+title: createSyncStoragePersister
+---
+
+## 安装
+
+该工具作为独立包提供,可通过 `'@tanstack/query-sync-storage-persister'` 导入使用。
+
+```bash
+npm install @tanstack/query-sync-storage-persister @tanstack/react-query-persist-client
+```
+
+或
+
+```bash
+pnpm add @tanstack/query-sync-storage-persister @tanstack/react-query-persist-client
+```
+
+或
+
+```bash
+yarn add @tanstack/query-sync-storage-persister @tanstack/react-query-persist-client
+```
+
+或
+
+```bash
+bun add @tanstack/query-sync-storage-persister @tanstack/react-query-persist-client
+```
+
+## 使用方式
+
+- 导入 `createSyncStoragePersister` 函数
+- 创建新的 syncStoragePersister 实例
+- 将其传递给 [`persistQueryClient`](./persistQueryClient.md) 函数
+
+```tsx
+import { persistQueryClient } from '@tanstack/react-query-persist-client'
+import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister'
+
+const queryClient = new QueryClient({
+ defaultOptions: {
+ queries: {
+ gcTime: 1000 * 60 * 60 * 24, // 24 小时
+ },
+ },
+})
+
+const localStoragePersister = createSyncStoragePersister({
+ storage: window.localStorage,
+})
+// const sessionStoragePersister = createSyncStoragePersister({ storage: window.sessionStorage })
+
+persistQueryClient({
+ queryClient,
+ persister: localStoragePersister,
+})
+```
+
+## 重试机制
+
+持久化可能失败(例如当数据大小超出存储空间时)。通过向 persister 提供 `retry` 函数可以优雅处理错误。
+
+重试函数接收尝试保存的 `persistedClient`、发生的 `error` 以及重试次数 `errorCount` 作为输入。它应返回一个*新的* `PersistedClient` 用于再次尝试持久化。若返回 _undefined_ 则表示不再尝试。
+
+```tsx
+export type PersistRetryer = (props: {
+ persistedClient: PersistedClient
+ error: Error
+ errorCount: number
+}) => PersistedClient | undefined
+```
+
+### 预定义策略
+
+默认情况下不会进行重试。您可以使用以下预定义策略处理重试(需从 `'@tanstack/react-query-persist-client'` 导入):
+
+- `removeOldestQuery`
+ - 返回移除最旧查询后的新 `PersistedClient`
+
+```tsx
+const localStoragePersister = createSyncStoragePersister({
+ storage: window.localStorage,
+ retry: removeOldestQuery,
+})
+```
+
+## API 接口
+
+### `createSyncStoragePersister`
+
+调用此函数创建 syncStoragePersister 实例,后续可配合 `persistQueryClient` 使用。
+
+```tsx
+createSyncStoragePersister(options: CreateSyncStoragePersisterOptions)
+```
+
+### 配置选项
+
+```tsx
+interface CreateSyncStoragePersisterOptions {
+ /** 用于缓存存取的存储客户端 (window.localStorage 或 window.sessionStorage) */
+ storage: Storage | undefined | null
+ /** 存储缓存时使用的键名 */
+ key?: string
+ /** 为避免频繁操作,
+ * 可设置节流时间(毫秒)来控制存储频率 */
+ throttleTime?: number
+ /** 数据序列化方法 */
+ serialize?: (client: PersistedClient) => string
+ /** 数据反序列化方法 */
+ deserialize?: (cachedString: string) => PersistedClient
+ /** 错误时的重试策略 **/
+ retry?: PersistRetryer
+}
+```
+
+默认配置为:
+
+```tsx
+{
+ key = `REACT_QUERY_OFFLINE_CACHE`,
+ throttleTime = 1000,
+ serialize = JSON.stringify,
+ deserialize = JSON.parse,
+}
+```
+
+#### `serialize` 与 `deserialize` 选项
+
+`localStorage` 存在存储容量限制。如需存储更多数据,可覆写这两个函数,使用 [lz-string](https://github.com/pieroxy/lz-string/) 等库进行数据压缩/解压。
+
+```tsx
+import { QueryClient } from '@tanstack/react-query'
+import { persistQueryClient } from '@tanstack/react-query-persist-client'
+import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister'
+
+import { compress, decompress } from 'lz-string'
+
+const queryClient = new QueryClient({
+ defaultOptions: { queries: { staleTime: Infinity } },
+})
+
+persistQueryClient({
+ queryClient: queryClient,
+ persister: createSyncStoragePersister({
+ storage: window.localStorage,
+ serialize: (data) => compress(JSON.stringify(data)),
+ deserialize: (data) => JSON.parse(decompress(data)),
+ }),
+ maxAge: Infinity,
+})
+```
diff --git a/docs/zh-hans/framework/react/plugins/persistQueryClient.md b/docs/zh-hans/framework/react/plugins/persistQueryClient.md
new file mode 100644
index 00000000000..083d590f253
--- /dev/null
+++ b/docs/zh-hans/framework/react/plugins/persistQueryClient.md
@@ -0,0 +1,288 @@
+---
+source-updated-at: '2025-03-18T08:45:11.000Z'
+translation-updated-at: '2025-05-06T04:43:46.632Z'
+id: persistQueryClient
+title: persistQueryClient
+---
+
+这是一套用于与“持久化工具 (persisters)”交互的工具集,它们能保存你的 `queryClient` 以供后续使用。不同的 **持久化工具 (persisters)** 可将客户端和缓存存储到多种不同的存储层中。
+
+## 构建持久化工具
+
+- [createSyncStoragePersister](./createSyncStoragePersister.md)
+- [createAsyncStoragePersister](./createAsyncStoragePersister.md)
+- [创建自定义持久化工具](#persisters)
+
+## 工作原理
+
+**重要提示** - 为确保持久化正常工作,你可能需要在 `QueryClient` 中传递 `gcTime` 值以覆盖默认的水合 (hydration) 设置(如上所示)。
+
+如果在创建 `QueryClient` 实例时未设置此值,水合阶段将默认使用 `300000`(5 分钟),且存储的缓存会在 5 分钟不活动后被丢弃。这是默认的垃圾回收行为。
+
+该值应设置为与 `persistQueryClient` 的 `maxAge` 选项相同或更高。例如,若 `maxAge` 为 24 小时(默认值),则 `gcTime` 应设为 24 小时或更长。若低于 `maxAge`,垃圾回收会提前触发并丢弃存储的缓存。
+
+你也可以传递 `Infinity` 来完全禁用垃圾回收行为。
+
+由于 JavaScript 的限制,最大允许的 `gcTime` 约为 24 天(详见[更多信息](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#maximum_delay_value))。
+
+```tsx
+const queryClient = new QueryClient({
+ defaultOptions: {
+ queries: {
+ gcTime: 1000 * 60 * 60 * 24, // 24 小时
+ },
+ },
+})
+```
+
+### 缓存清除 (Cache Busting)
+
+有时你可能对应用或数据进行了更改,这些更改会立即使所有缓存数据失效。此时,你可以传递一个 `buster` 字符串选项。如果找到的缓存不包含该字符串,它将被丢弃。以下多个函数接受此选项:
+
+```tsx
+persistQueryClient({ queryClient, persister, buster: buildHash })
+persistQueryClientSave({ queryClient, persister, buster: buildHash })
+persistQueryClientRestore({ queryClient, persister, buster: buildHash })
+```
+
+### 移除机制
+
+如果数据满足以下任一条件:
+
+1. 已过期(见 `maxAge`)
+2. 已清除(见 `buster`)
+3. 出现错误(如 `throws ...`)
+4. 为空(如 `undefined`)
+
+持久化工具的 `removeClient()` 将被调用,缓存会立即被丢弃。
+
+## API
+
+### `persistQueryClientSave`
+
+- 你的查询/突变会被 [`脱水 (dehydrated)`](../reference/hydration.md#dehydrate) 并通过你提供的持久化工具存储。
+- `createSyncStoragePersister` 和 `createAsyncStoragePersister` 会对此操作进行节流,最多每 1 秒执行一次,以避免潜在的昂贵写入。查阅其文档以了解如何自定义节流时间。
+
+你可以用它在选择的时刻显式持久化缓存。
+
+```tsx
+persistQueryClientSave({
+ queryClient,
+ persister,
+ buster = '',
+ dehydrateOptions = undefined,
+})
+```
+
+### `persistQueryClientSubscribe`
+
+每当 `queryClient` 的缓存发生变化时运行 `persistQueryClientSave`。例如:你可以在用户登录并勾选“记住我”时启动 `subscribe`。
+
+- 它返回一个 `unsubscribe` 函数,可用于停止监听,结束对持久化缓存的更新。
+- 如果希望在 `unsubscribe` 后清除持久化缓存,可以向 `persistQueryClientRestore` 发送一个新的 `buster`,这将触发持久化工具的 `removeClient` 函数并丢弃持久化缓存。
+
+```tsx
+persistQueryClientSubscribe({
+ queryClient,
+ persister,
+ buster = '',
+ dehydrateOptions = undefined,
+})
+```
+
+### `persistQueryClientRestore`
+
+- 尝试从持久化工具中 [`水合 (hydrate)`](../reference/hydration.md#hydrate) 先前脱水的查询/突变缓存,将其恢复到传入的查询客户端中。
+- 如果找到的缓存比 `maxAge`(默认为 24 小时)更旧,它将被丢弃。此时间可根据需要自定义。
+
+你可以用它在选择的时刻恢复缓存。
+
+```tsx
+persistQueryClientRestore({
+ queryClient,
+ persister,
+ maxAge = 1000 * 60 * 60 * 24, // 24 小时
+ buster = '',
+ hydrateOptions = undefined,
+})
+```
+
+### `persistQueryClient`
+
+执行以下操作:
+
+1. 立即恢复所有持久化缓存(见 [`persistQueryClientRestore`](#persistqueryclientrestore))
+2. 订阅查询缓存并返回 `unsubscribe` 函数(见 [`persistQueryClientSubscribe`](#persistqueryclientsubscribe))。
+
+此功能从 3.x 版本保留至今。
+
+```tsx
+persistQueryClient({
+ queryClient,
+ persister,
+ maxAge = 1000 * 60 * 60 * 24, // 24 小时
+ buster = '',
+ hydrateOptions = undefined,
+ dehydrateOptions = undefined,
+})
+```
+
+### `Options`
+
+所有可用选项如下:
+
+```tsx
+interface PersistQueryClientOptions {
+ /** 需要持久化的 QueryClient */
+ queryClient: QueryClient
+ /** 用于存储和恢复缓存的持久化工具接口 */
+ persister: Persister
+ /** 缓存的最大允许存活时间(毫秒)。
+ * 如果找到的持久化缓存比此时间更旧,
+ * 它将 **静默** 被丢弃(默认为 24 小时) */
+ maxAge?: number
+ /** 用于强制使现有缓存失效的唯一字符串,
+ * 如果它们不共享相同的 buster 字符串 */
+ buster?: string
+ /** 传递给 hydrate 函数的选项,
+ * 不用于 `persistQueryClientSave` 或 `persistQueryClientSubscribe` */
+ hydrateOptions?: HydrateOptions
+ /** 传递给 dehydrate 函数的选项,
+ * 不用于 `persistQueryClientRestore` */
+ dehydrateOptions?: DehydrateOptions
+}
+```
+
+实际上有三种接口可用:
+
+- `PersistedQueryClientSaveOptions` 用于 `persistQueryClientSave` 和 `persistQueryClientSubscribe`(不使用 `hydrateOptions`)。
+- `PersistedQueryClientRestoreOptions` 用于 `persistQueryClientRestore`(不使用 `dehydrateOptions`)。
+- `PersistQueryClientOptions` 用于 `persistQueryClient`
+
+## 与 React 一起使用
+
+[persistQueryClient](#persistQueryClient) 会尝试恢复缓存并自动订阅后续更改,从而将你的客户端同步到提供的存储中。
+
+然而,恢复是异步的,因为所有持久化工具本质上都是异步的。这意味着如果在恢复过程中渲染应用,可能会在查询挂载和获取同时发生时遇到竞态条件。
+
+此外,如果在 React 组件生命周期之外订阅更改,你将无法取消订阅:
+
+```tsx
+// 🚨 永远不会停止同步订阅
+persistQueryClient({
+ queryClient,
+ persister: localStoragePersister,
+})
+
+// 🚨 与恢复同时发生
+ReactDOM.createRoot(rootElement).render( )
+```
+
+### PersistQueryClientProvider
+
+针对此用例,你可以使用 `PersistQueryClientProvider`。它会根据 React 组件生命周期正确订阅/取消订阅,并确保在恢复过程中查询不会开始获取。查询仍会渲染,但它们会被置为 `fetchingState: 'idle'`,直到数据恢复完成。之后,除非恢复的数据足够新,否则它们会重新获取,同时也会尊重 `initialData`。它可以替代普通的 [QueryClientProvider](../reference/QueryClientProvider.md):
+
+```tsx
+import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client'
+import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister'
+
+const queryClient = new QueryClient({
+ defaultOptions: {
+ queries: {
+ gcTime: 1000 * 60 * 60 * 24, // 24 小时
+ },
+ },
+})
+
+const persister = createSyncStoragePersister({
+ storage: window.localStorage,
+})
+
+ReactDOM.createRoot(rootElement).render(
+
+
+ ,
+)
+```
+
+#### Props
+
+`PersistQueryClientProvider` 接受与 [QueryClientProvider](../reference/QueryClientProvider.md) 相同的 props,并额外包括:
+
+- `persistOptions: PersistQueryClientOptions`
+ - 所有可传递给 [persistQueryClient](#persistqueryclient) 的[选项](#options),但不包括 `QueryClient` 本身
+- `onSuccess?: () => Promise | unknown`
+ - 可选
+ - 初始恢复完成时调用
+ - 可用于 [resumePausedMutations](../../../reference/QueryClient.md#queryclientresumepausedmutations)
+ - 如果返回 Promise,会等待其完成;恢复过程在此期间被视为进行中
+
+### useIsRestoring
+
+如果使用 `PersistQueryClientProvider`,还可以配合使用 `useIsRestoring` 钩子来检查当前是否正在进行恢复。`useQuery` 等函数内部也会检查此状态,以避免恢复和挂载查询之间的竞态条件。
+
+## 持久化工具
+
+### 持久化工具接口
+
+持久化工具具有以下接口:
+
+```tsx
+export interface Persister {
+ persistClient(persistClient: PersistedClient): Promisable
+ restoreClient(): Promisable
+ removeClient(): Promisable
+}
+```
+
+持久化客户端条目具有以下接口:
+
+```tsx
+export interface PersistedClient {
+ timestamp: number
+ buster: string
+ cacheState: any
+}
+```
+
+你可以导入这些接口(以构建持久化工具):
+
+```tsx
+import {
+ PersistedClient,
+ Persister,
+} from '@tanstack/react-query-persist-client'
+```
+
+### 构建持久化工具
+
+你可以按需实现持久化。以下是一个构建 [Indexed DB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API) 持久化工具的示例。相比 `Web Storage API`,Indexed DB 更快,存储容量超过 5MB,且不需要序列化。这意味着它能直接存储 JavaScript 原生类型,如 `Date` 和 `File`。
+
+```tsx
+import { get, set, del } from 'idb-keyval'
+import {
+ PersistedClient,
+ Persister,
+} from '@tanstack/react-query-persist-client'
+
+/**
+ * 创建一个 Indexed DB 持久化工具
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API
+ */
+export function createIDBPersister(idbValidKey: IDBValidKey = 'reactQuery') {
+ return {
+ persistClient: async (client: PersistedClient) => {
+ await set(idbValidKey, client)
+ },
+ restoreClient: async () => {
+ return await get(idbValidKey)
+ },
+ removeClient: async () => {
+ await del(idbValidKey)
+ },
+ } satisfies Persister
+}
+```
diff --git a/docs/zh-hans/framework/react/quick-start.md b/docs/zh-hans/framework/react/quick-start.md
new file mode 100644
index 00000000000..64e42234357
--- /dev/null
+++ b/docs/zh-hans/framework/react/quick-start.md
@@ -0,0 +1,79 @@
+---
+source-updated-at: '2025-03-18T08:45:11.000Z'
+translation-updated-at: '2025-05-03T21:51:49.019Z'
+id: quick-start
+title: 快速开始
+---
+
+以下代码片段简要展示了 React Query 的 3 个核心概念:
+
+- [查询 (Queries)](./guides/queries.md)
+- [变更 (Mutations)](./guides/mutations.md)
+- [查询失效 (Query Invalidation)](./guides/query-invalidation.md)
+
+[//]: # '示例'
+
+如需查看完整功能示例,请参考我们的 [简单 StackBlitz 示例](../examples/simple)
+
+```tsx
+import {
+ useQuery,
+ useMutation,
+ useQueryClient,
+ QueryClient,
+ QueryClientProvider,
+} from '@tanstack/react-query'
+import { getTodos, postTodo } from '../my-api'
+
+// 创建客户端
+const queryClient = new QueryClient()
+
+function App() {
+ return (
+ // 将客户端提供给应用
+
+
+
+ )
+}
+
+function Todos() {
+ // 访问客户端
+ const queryClient = useQueryClient()
+
+ // 查询
+ const query = useQuery({ queryKey: ['todos'], queryFn: getTodos })
+
+ // 变更
+ const mutation = useMutation({
+ mutationFn: postTodo,
+ onSuccess: () => {
+ // 使缓存失效并重新获取
+ queryClient.invalidateQueries({ queryKey: ['todos'] })
+ },
+ })
+
+ return (
+
+
{query.data?.map((todo) => {todo.title} )}
+
+
{
+ mutation.mutate({
+ id: Date.now(),
+ title: 'Do Laundry',
+ })
+ }}
+ >
+ 添加待办
+
+
+ )
+}
+
+render( , document.getElementById('root'))
+```
+
+[//]: # '示例'
+
+这三个概念构成了 React Query 的大部分核心功能。文档的后续章节将详细讲解每个核心概念。
diff --git a/docs/zh-hans/framework/react/react-native.md b/docs/zh-hans/framework/react/react-native.md
new file mode 100644
index 00000000000..b57b96f91f8
--- /dev/null
+++ b/docs/zh-hans/framework/react/react-native.md
@@ -0,0 +1,119 @@
+---
+source-updated-at: '2025-02-12T15:01:46.000Z'
+translation-updated-at: '2025-05-06T04:25:35.500Z'
+id: react-native
+title: React Native
+---
+
+React Query 设计上可直接在 React Native 中开箱使用,但目前开发工具(devtools)仅支持 React DOM。
+
+您可以尝试以下第三方插件:
+
+- [Expo](https://docs.expo.dev/) 插件:https://github.com/expo/dev-plugins/tree/main/packages/react-query
+- [Flipper](https://fbflipper.com/docs/getting-started/react-native/) 插件:https://github.com/bgaleotti/react-query-native-devtools
+- [Reactotron](https://github.com/infinitered/reactotron/) 插件:https://github.com/hsndmr/reactotron-react-query
+
+若您愿意协助我们开发跨平台的内置开发工具,欢迎随时联系!
+
+## 在线状态管理
+
+React Query 已支持浏览器断网重连后自动重新请求数据。在 React Native 中实现该功能需使用 `onlineManager`,示例如下:
+
+```tsx
+import NetInfo from '@react-native-community/netinfo'
+import { onlineManager } from '@tanstack/react-query'
+
+onlineManager.setEventListener((setOnline) => {
+ return NetInfo.addEventListener((state) => {
+ setOnline(!!state.isConnected)
+ })
+})
+```
+
+或
+
+```tsx
+import { onlineManager } from '@tanstack/react-query'
+import * as Network from 'expo-network'
+
+onlineManager.setEventListener((setOnline) => {
+ const eventSubscription = Network.addNetworkStateListener((state) => {
+ setOnline(!!state.isConnected)
+ })
+ return eventSubscription.remove
+})
+```
+
+## 应用聚焦时重新请求
+
+不同于浏览器监听 `window` 事件,React Native 通过 [`AppState` 模块](https://reactnative.dev/docs/appstate#app-states) 提供应用状态信息。可利用 "change" 事件在应用状态变为 "active" 时触发更新:
+
+```tsx
+import { useEffect } from 'react'
+import { AppState, Platform } from 'react-native'
+import type { AppStateStatus } from 'react-native'
+import { focusManager } from '@tanstack/react-query'
+
+function onAppStateChange(status: AppStateStatus) {
+ if (Platform.OS !== 'web') {
+ focusManager.setFocused(status === 'active')
+ }
+}
+
+useEffect(() => {
+ const subscription = AppState.addEventListener('change', onAppStateChange)
+
+ return () => subscription.remove()
+}, [])
+```
+
+## 屏幕聚焦时刷新
+
+某些场景下,您可能需要在 React Native 屏幕重新聚焦时重新请求数据。以下自定义钩子会在屏幕聚焦时调用传入的 `refetch` 方法:
+
+```tsx
+import React from 'react'
+import { useFocusEffect } from '@react-navigation/native'
+
+export function useRefreshOnFocus(refetch: () => Promise) {
+ const firstTimeRef = React.useRef(true)
+
+ useFocusEffect(
+ React.useCallback(() => {
+ if (firstTimeRef.current) {
+ firstTimeRef.current = false
+ return
+ }
+
+ refetch()
+ }, [refetch]),
+ )
+}
+```
+
+上述代码中首次加载会跳过 `refetch`,因为 `useFocusEffect` 在组件挂载时也会触发回调。
+
+## 禁用非聚焦屏幕的查询
+
+若您不希望某些查询在屏幕失焦时保持活跃状态,可通过 `useQuery` 的 `subscribed` 属性控制查询是否持续订阅更新。结合 React Navigation 的 `useIsFocused`,可实现屏幕失焦时自动取消订阅:
+
+```tsx
+import React from 'react'
+import { useIsFocused } from '@react-navigation/native'
+import { useQuery } from '@tanstack/react-query'
+import { Text } from 'react-native'
+
+function MyComponent() {
+ const isFocused = useIsFocused()
+
+ const { dataUpdatedAt } = useQuery({
+ queryKey: ['key'],
+ queryFn: () => fetch(...),
+ subscribed: isFocused,
+ })
+
+ return DataUpdatedAt: {dataUpdatedAt}
+}
+```
+
+当 `subscribed` 为 `false` 时,查询将取消订阅更新,既不会触发重渲染也不会为该屏幕获取新数据。当值恢复为 `true`(例如屏幕重新聚焦时),查询会重新订阅并保持数据最新。
diff --git a/docs/zh-hans/framework/react/reference/QueryClientProvider.md b/docs/zh-hans/framework/react/reference/QueryClientProvider.md
new file mode 100644
index 00000000000..849cacfd9f3
--- /dev/null
+++ b/docs/zh-hans/framework/react/reference/QueryClientProvider.md
@@ -0,0 +1,24 @@
+---
+source-updated-at: '2024-01-25T20:57:22.000Z'
+translation-updated-at: '2025-05-06T04:41:57.472Z'
+id: QueryClientProvider
+title: QueryClientProvider
+---
+
+使用 `QueryClientProvider` 组件将 `QueryClient` 连接并提供给您的应用:
+
+```tsx
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
+
+const queryClient = new QueryClient()
+
+function App() {
+ return ...
+}
+```
+
+**配置项**
+
+- `client: QueryClient`
+ - **必填**
+ - 需要提供的 QueryClient 实例
diff --git a/docs/zh-hans/framework/react/reference/QueryErrorResetBoundary.md b/docs/zh-hans/framework/react/reference/QueryErrorResetBoundary.md
new file mode 100644
index 00000000000..0ee339a906f
--- /dev/null
+++ b/docs/zh-hans/framework/react/reference/QueryErrorResetBoundary.md
@@ -0,0 +1,66 @@
+---
+source-updated-at: '2024-04-11T09:16:39.000Z'
+translation-updated-at: '2025-05-06T04:41:50.065Z'
+id: QueryErrorResetBoundary
+title: QueryErrorResetBoundary
+---
+
+## 动机
+
+大多数核心 Web 框架**并未**提供一种全面的数据获取或更新方案。因此,开发者最终要么构建封装了严格数据获取规范的元框架,要么自行发明数据获取方式。这通常意味着拼凑基于组件的状态和副作用,或是使用更通用的状态管理库来存储并提供应用中的异步数据。
+
+虽然大多数传统状态管理库非常适合处理客户端状态,但它们**在处理异步或服务端状态时表现欠佳**。这是因为**服务端状态完全不同**。首先,服务端状态:
+
+- 持久化存储在您可能无法控制或拥有的远程位置
+- 需要通过异步 API 进行获取和更新
+- 意味着共享所有权,可能被他人更改而您不知情
+- 如果不加注意,可能在应用中变得"过时"
+
+一旦理解了应用中服务端状态的本质,**更多挑战将接踵而至**,例如:
+
+- 缓存...(可能是编程中最难实现的部分)
+- 将针对相同数据的多个请求去重为单个请求
+- 在后台更新"过时"数据
+- 判断数据何时"过时"
+- 尽可能快地反映数据更新
+- 分页和懒加载等性能优化
+- 管理服务端状态的内存和垃圾回收
+- 通过结构共享记忆化查询结果
+
+如果您没有被这个清单吓到,那一定意味着您已经解决了所有服务端状态问题并值得嘉奖。然而,如果您像绝大多数人一样,那么您要么尚未解决全部或大部分挑战,而我们才刚刚触及表面!
+
+TanStack Query 无疑是管理服务端状态的最佳库之一。它开箱即用,零配置就能表现出色,并且可以随着应用增长按需定制。
+
+TanStack Query 让您能够战胜和克服服务端状态的各种棘手挑战,在应用数据控制您之前掌控它们。
+
+从技术角度而言,TanStack Query 很可能:
+
+- 帮助您从应用中移除**大量**复杂且难以理解的代码,仅用几行 TanStack Query 逻辑替代
+- 提高应用的可维护性,更轻松地构建新功能而无需担心连接新的服务端状态数据源
+- 通过使应用感觉比以往更快、响应更迅速,直接影响最终用户体验
+- 可能帮助节省带宽并提升内存性能
+
+当在查询中使用 **suspense** 或 **throwOnError** 时,您需要一种方式让查询知道在发生错误后重新渲染时您想重试。通过 `QueryErrorResetBoundary` 组件,您可以重置组件边界内的任何查询错误。
+
+```tsx
+import { QueryErrorResetBoundary } from '@tanstack/react-query'
+import { ErrorBoundary } from 'react-error-boundary'
+
+const App = () => (
+
+ {({ reset }) => (
+ (
+
+ There was an error!
+ resetErrorBoundary()}>Try again
+
+ )}
+ >
+
+
+ )}
+
+)
+```
diff --git a/docs/zh-hans/framework/react/reference/hydration.md b/docs/zh-hans/framework/react/reference/hydration.md
new file mode 100644
index 00000000000..a934fa22ec2
--- /dev/null
+++ b/docs/zh-hans/framework/react/reference/hydration.md
@@ -0,0 +1,130 @@
+---
+source-updated-at: '2025-02-17T12:52:17.000Z'
+translation-updated-at: '2025-05-06T04:41:17.708Z'
+id: hydration
+title: 注水
+---
+
+## `dehydrate`
+
+`dehydrate` 会创建一个 `cache` 的冻结表示,后续可通过 `HydrationBoundary` 或 `hydrate` 进行水合。这在将预取查询从服务端传递到客户端,或将查询持久化到 localStorage 或其他持久化存储时非常有用。默认情况下,它仅包含当前成功的查询。
+
+```tsx
+import { dehydrate } from '@tanstack/react-query'
+
+const dehydratedState = dehydrate(queryClient, {
+ shouldDehydrateQuery,
+ shouldDehydrateMutation,
+})
+```
+
+**选项**
+
+- `client: QueryClient`
+ - **必填**
+ - 需要被脱水的 `queryClient`
+- `options: DehydrateOptions`
+ - 可选
+ - `shouldDehydrateMutation: (mutation: Mutation) => boolean`
+ - 可选
+ - 是否对变更 (mutation) 进行脱水
+ - 该函数会针对缓存中的每个变更被调用
+ - 返回 `true` 表示将此变更包含在脱水中,否则返回 `false`
+ - 默认仅包含暂停的变更
+ - 若希望在保留默认行为的同时扩展此函数,可在返回语句中导入并执行 `defaultShouldDehydrateMutation`
+ - `shouldDehydrateQuery: (query: Query) => boolean`
+ - 可选
+ - 是否对查询进行脱水
+ - 该函数会针对缓存中的每个查询被调用
+ - 返回 `true` 表示将此查询包含在脱水中,否则返回 `false`
+ - 默认仅包含成功的查询
+ - 若希望在保留默认行为的同时扩展此函数,可在返回语句中导入并执行 `defaultShouldDehydrateQuery`
+ - `serializeData?: (data: any) => any` 用于在脱水期间转换(序列化)数据的函数
+ - `shouldRedactErrors?: (error: unknown) => boolean`
+ - 可选
+ - 是否在脱水过程中对来自服务端的错误进行脱敏
+ - 该函数会针对缓存中的每个错误被调用
+ - 返回 `true` 表示对此错误脱敏,否则返回 `false`
+ - 默认会对所有错误脱敏
+
+**返回值**
+
+- `dehydratedState: DehydratedState`
+ - 包含后续水合 `queryClient` 所需的所有内容
+ - 你**不应**依赖此响应的具体格式,它不属于公共 API 且可能随时变更
+ - 此结果未经过序列化处理,如有需要请自行序列化
+
+### 限制
+
+某些存储系统(如浏览器的 [Web Storage API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API))要求值必须可 JSON 序列化。如果你需要脱水无法自动序列化为 JSON 的值(如 `Error` 或 `undefined`),必须自行序列化。由于默认仅包含成功的查询,若要同时包含 `Errors`,需提供 `shouldDehydrateQuery`,例如:
+
+```tsx
+// 服务端
+const state = dehydrate(client, { shouldDehydrateQuery: () => true }) // 同时包含 Errors
+const serializedState = mySerialize(state) // 将 Error 实例转换为对象
+
+// 客户端
+const state = myDeserialize(serializedState) // 将对象转换回 Error 实例
+hydrate(client, state)
+```
+
+## `hydrate`
+
+`hydrate` 将先前脱水的状态添加回 `cache` 中。
+
+```tsx
+import { hydrate } from '@tanstack/react-query'
+
+hydrate(queryClient, dehydratedState, options)
+```
+
+**选项**
+
+- `client: QueryClient`
+ - **必填**
+ - 要注入状态的 `queryClient`
+- `dehydratedState: DehydratedState`
+ - **必填**
+ - 要注入到客户端的状态
+- `options: HydrateOptions`
+ - 可选
+ - `defaultOptions: DefaultOptions`
+ - 可选
+ - `mutations: MutationOptions` 用于已水合变更的默认变更选项
+ - `queries: QueryOptions` 用于已水合查询的默认查询选项
+ - `deserializeData?: (data: any) => any` 在将数据放入缓存前对其进行转换(反序列化)的函数
+ - `queryClient?: QueryClient`
+ - 使用此选项可指定自定义 QueryClient。否则将使用最近上下文中的 QueryClient
+
+### 限制
+
+若尝试水合的查询已存在于 queryCache 中,`hydrate` 仅会在数据比缓存中现有数据更新时覆盖它们。否则,这些数据**不会**被应用。
+
+[//]: # 'HydrationBoundary'
+
+## `HydrationBoundary`
+
+`HydrationBoundary` 将先前脱水的状态注入到由 `useQueryClient()` 返回的 `queryClient` 中。如果客户端已包含数据,新查询将基于更新时间戳智能合并。
+
+```tsx
+import { HydrationBoundary } from '@tanstack/react-query'
+
+function App() {
+ return ...
+}
+```
+
+> 注意:只有 `queries` 可以通过 `HydrationBoundary` 进行脱水
+
+**选项**
+
+- `state: DehydratedState`
+ - 要水合的状态
+- `options: HydrateOptions`
+ - 可选
+ - `defaultOptions: QueryOptions`
+ - 用于已水合查询的默认查询选项
+ - `queryClient?: QueryClient`
+ - 使用此选项可指定自定义 QueryClient。否则将使用最近上下文中的 QueryClient
+
+[//]: # 'HydrationBoundary'
diff --git a/docs/zh-hans/framework/react/reference/infiniteQueryOptions.md b/docs/zh-hans/framework/react/reference/infiniteQueryOptions.md
new file mode 100644
index 00000000000..56ad6414414
--- /dev/null
+++ b/docs/zh-hans/framework/react/reference/infiniteQueryOptions.md
@@ -0,0 +1,21 @@
+---
+source-updated-at: '2025-03-18T08:45:11.000Z'
+translation-updated-at: '2025-05-06T04:40:23.130Z'
+id: infiniteQueryOptions
+title: infiniteQueryOptions
+---
+
+```tsx
+infiniteQueryOptions({
+ queryKey,
+ ...options,
+})
+```
+
+**选项配置**
+
+通常你可以向 `infiniteQueryOptions` 传递所有 [`useInfiniteQuery`](./useInfiniteQuery.md) 支持的参数。部分选项在被转发到如 `queryClient.prefetchInfiniteQuery` 这类函数时不会生效,但 TypeScript 仍会允许这些额外的属性存在。
+
+- `queryKey: QueryKey`
+ - **必填**
+ - 用于生成选项配置的查询键 (Query Key)。
diff --git a/docs/zh-hans/framework/react/reference/queryOptions.md b/docs/zh-hans/framework/react/reference/queryOptions.md
new file mode 100644
index 00000000000..a9771fad195
--- /dev/null
+++ b/docs/zh-hans/framework/react/reference/queryOptions.md
@@ -0,0 +1,26 @@
+---
+source-updated-at: '2025-03-18T08:45:11.000Z'
+translation-updated-at: '2025-05-06T04:40:14.841Z'
+id: queryOptions
+title: queryOptions
+---
+
+```tsx
+queryOptions({
+ queryKey,
+ ...options,
+})
+```
+
+**选项**
+
+通常你可以向 `queryOptions` 传递所有能传递给 [`useQuery`](./useQuery.md) 的参数。部分选项在被转发到类似 `queryClient.prefetchQuery` 的函数时不会生效,但 TypeScript 仍会允许这些额外属性的存在。
+
+- `queryKey: QueryKey`
+ - **必填**
+ - 用于生成选项的查询键 (query key)
+- `experimental_prefetchInRender?: boolean`
+ - 可选
+ - 默认为 `false`
+ - 设为 `true` 时,查询将在渲染期间预取,这对某些优化场景很有用
+ - 需要开启此选项才能使用实验性的 `useQuery().promise` 功能
diff --git a/docs/zh-hans/framework/react/reference/useInfiniteQuery.md b/docs/zh-hans/framework/react/reference/useInfiniteQuery.md
new file mode 100644
index 00000000000..50383e47b93
--- /dev/null
+++ b/docs/zh-hans/framework/react/reference/useInfiniteQuery.md
@@ -0,0 +1,94 @@
+---
+source-updated-at: '2025-03-18T08:45:11.000Z'
+translation-updated-at: '2025-05-06T04:40:03.526Z'
+id: useInfiniteQuery
+title: useInfiniteQuery
+---
+
+```tsx
+const {
+ fetchNextPage,
+ fetchPreviousPage,
+ hasNextPage,
+ hasPreviousPage,
+ isFetchingNextPage,
+ isFetchingPreviousPage,
+ promise,
+ ...result
+} = useInfiniteQuery({
+ queryKey,
+ queryFn: ({ pageParam }) => fetchPage(pageParam),
+ initialPageParam: 1,
+ ...options,
+ getNextPageParam: (lastPage, allPages, lastPageParam, allPageParams) =>
+ lastPage.nextCursor,
+ getPreviousPageParam: (firstPage, allPages, firstPageParam, allPageParams) =>
+ firstPage.prevCursor,
+})
+```
+
+**选项**
+
+`useInfiniteQuery` 的选项与 [`useQuery` 钩子](./useQuery.md) 相同,但额外包含以下参数:
+
+- `queryFn: (context: QueryFunctionContext) => Promise`
+ - **必填(仅当未定义默认查询函数时)** [`defaultQueryFn`](../guides/default-query-function.md)
+ - 查询用于请求数据的函数。
+ - 接收一个 [QueryFunctionContext](../guides/query-functions.md#queryfunctioncontext) 对象。
+ - 必须返回一个会解析为数据或抛出错误的 Promise。
+- `initialPageParam: TPageParam`
+ - **必填**
+ - 获取第一页时使用的默认页面参数。
+- `getNextPageParam: (lastPage, allPages, lastPageParam, allPageParams) => TPageParam | undefined | null`
+ - **必填**
+ - 当查询接收到新数据时,此函数会接收无限数据列表的最后一页、所有页面的完整数组以及页面参数信息。
+ - 应返回一个**单一变量**,该变量将作为最后一个可选参数传递给查询函数。
+ - 返回 `undefined` 或 `null` 表示没有下一页可用。
+- `getPreviousPageParam: (firstPage, allPages, firstPageParam, allPageParams) => TPageParam | undefined | null`
+ - 当查询接收到新数据时,此函数会接收无限数据列表的第一页、所有页面的完整数组以及页面参数信息。
+ - 应返回一个**单一变量**,该变量将作为最后一个可选参数传递给查询函数。
+ - 返回 `undefined` 或 `null` 表示没有上一页可用。
+- `maxPages: number | undefined`
+ - 无限查询数据中存储的最大页数。
+ - 当达到最大页数时,获取新页将导致从页面数组中移除第一页或最后一页(取决于指定的方向)。
+ - 如果为 `undefined` 或等于 `0`,则页数不受限制。
+ - 默认值为 `undefined`。
+ - 如果 `maxPages` 值大于 `0`,则必须正确定义 `getNextPageParam` 和 `getPreviousPageParam`,以便在需要时允许双向获取页面。
+
+**返回值**
+
+`useInfiniteQuery` 返回的属性与 [`useQuery` 钩子](./useQuery.md) 相同,但额外包含以下属性,且 `isRefetching` 和 `isRefetchError` 略有不同:
+
+- `data.pages: TData[]`
+ - 包含所有页面的数组。
+- `data.pageParams: unknown[]`
+ - 包含所有页面参数的数组。
+- `isFetchingNextPage: boolean`
+ - 当通过 `fetchNextPage` 获取下一页时为 `true`。
+- `isFetchingPreviousPage: boolean`
+ - 当通过 `fetchPreviousPage` 获取上一页时为 `true`。
+- `fetchNextPage: (options?: FetchNextPageOptions) => Promise`
+ - 此函数允许你获取下一页结果。
+ - `options.cancelRefetch: boolean` 如果设置为 `true`,重复调用 `fetchNextPage` 将每次触发 `queryFn`,无论之前的调用是否已解析。同时,之前调用的结果将被忽略。如果设置为 `false`,重复调用 `fetchNextPage` 在第一次调用解析前不会产生任何效果。默认为 `true`。
+- `fetchPreviousPage: (options?: FetchPreviousPageOptions) => Promise`
+ - 此函数允许你获取上一页结果。
+ - `options.cancelRefetch: boolean` 与 `fetchNextPage` 相同。
+- `hasNextPage: boolean`
+ - 如果存在可获取的下一页(通过 `getNextPageParam` 选项判断)则为 `true`。
+- `hasPreviousPage: boolean`
+ - 如果存在可获取的上一页(通过 `getPreviousPageParam` 选项判断)则为 `true`。
+- `isFetchNextPageError: boolean`
+ - 如果获取下一页时查询失败则为 `true`。
+- `isFetchPreviousPageError: boolean`
+ - 如果获取上一页时查询失败则为 `true`。
+- `isRefetching: boolean`
+ - 当后台重新获取正在进行时为 `true`,**不包括**初始的 `pending` 状态或获取下一页/上一页的操作。
+ - 等同于 `isFetching && !isPending && !isFetchingNextPage && !isFetchingPreviousPage`。
+- `isRefetchError: boolean`
+ - 如果重新获取页面时查询失败则为 `true`。
+- `promise: Promise`
+ - 一个稳定的 Promise,解析为查询结果。
+ - 可与 `React.use()` 配合使用以获取数据。
+ - 需要在 `QueryClient` 上启用 `experimental_prefetchInRender` 特性标志。
+
+请注意,命令式获取调用(如 `fetchNextPage`)可能会干扰默认的重新获取行为,导致数据过时。确保仅在响应用户操作时调用这些函数,或添加类似 `hasNextPage && !isFetching` 的条件。
diff --git a/docs/zh-hans/framework/react/reference/useIsFetching.md b/docs/zh-hans/framework/react/reference/useIsFetching.md
new file mode 100644
index 00000000000..15c0bc8e0df
--- /dev/null
+++ b/docs/zh-hans/framework/react/reference/useIsFetching.md
@@ -0,0 +1,27 @@
+---
+source-updated-at: '2025-03-18T08:45:11.000Z'
+translation-updated-at: '2025-05-06T04:39:06.621Z'
+id: useIsFetching
+title: useIsFetching
+---
+
+`useIsFetching` 是一个可选钩子,返回当前应用在后台加载或获取中的查询 `数量`(适用于全局加载指示器)。
+
+```tsx
+import { useIsFetching } from '@tanstack/react-query'
+// 有多少查询正在获取中?
+const isFetching = useIsFetching()
+// 匹配 posts 前缀的查询有多少正在获取中?
+const isFetchingPosts = useIsFetching({ queryKey: ['posts'] })
+```
+
+**选项**
+
+- `filters?: QueryFilters`: [查询过滤器](../guides/filters.md#query-filters)
+- `queryClient?: QueryClient`,
+ - 使用此选项可指定自定义 QueryClient。否则将使用最近上下文中的 QueryClient。
+
+**返回值**
+
+- `isFetching: number`
+ - 表示当前应用在后台加载或获取中的查询数量。
diff --git a/docs/zh-hans/framework/react/reference/useIsMutating.md b/docs/zh-hans/framework/react/reference/useIsMutating.md
new file mode 100644
index 00000000000..ba7bf9a01f6
--- /dev/null
+++ b/docs/zh-hans/framework/react/reference/useIsMutating.md
@@ -0,0 +1,27 @@
+---
+source-updated-at: '2025-03-18T08:45:11.000Z'
+translation-updated-at: '2025-05-06T04:38:54.202Z'
+id: useIsMutating
+title: useIsMutating
+---
+
+`useIsMutating` 是一个可选钩子,用于返回当前应用中正在获取的变更操作(mutations)数量(适用于全局加载指示器场景)。
+
+```tsx
+import { useIsMutating } from '@tanstack/react-query'
+// 获取当前正在进行的变更操作数量
+const isMutating = useIsMutating()
+// 获取匹配 posts 前缀的变更操作数量
+const isMutatingPosts = useIsMutating({ mutationKey: ['posts'] })
+```
+
+**选项参数**
+
+- `filters?: MutationFilters`: [变更过滤器](../guides/filters.md#mutation-filters)
+- `queryClient?: QueryClient`,
+ - 用于指定自定义 QueryClient 实例。若未提供,则使用最近上下文中的实例。
+
+**返回值**
+
+- `isMutating: number`
+ - 返回当前应用中正在获取的变更操作数量。
diff --git a/docs/zh-hans/framework/react/reference/useMutation.md b/docs/zh-hans/framework/react/reference/useMutation.md
new file mode 100644
index 00000000000..f8e198f0c39
--- /dev/null
+++ b/docs/zh-hans/framework/react/reference/useMutation.md
@@ -0,0 +1,162 @@
+---
+source-updated-at: '2025-03-18T08:45:11.000Z'
+translation-updated-at: '2025-05-06T04:38:43.637Z'
+id: useMutation
+title: useMutation
+---
+
+```tsx
+const {
+ data,
+ error,
+ isError,
+ isIdle,
+ isPending,
+ isPaused,
+ isSuccess,
+ failureCount,
+ failureReason,
+ mutate,
+ mutateAsync,
+ reset,
+ status,
+ submittedAt,
+ variables,
+} = useMutation(
+ {
+ mutationFn,
+ gcTime,
+ meta,
+ mutationKey,
+ networkMode,
+ onError,
+ onMutate,
+ onSettled,
+ onSuccess,
+ retry,
+ retryDelay,
+ scope,
+ throwOnError,
+ },
+ queryClient,
+)
+
+mutate(variables, {
+ onError,
+ onSettled,
+ onSuccess,
+})
+```
+
+**参数1 (选项)**
+
+- `mutationFn: (variables: TVariables) => Promise`
+ - **必填(仅在未定义默认 mutation 函数时)**
+ - 执行异步任务并返回 Promise 的函数
+ - `variables` 是 `mutate` 将传递给 `mutationFn` 的对象
+- `gcTime: number | Infinity`
+ - 未使用/非活跃的缓存数据在内存中保留的时间(毫秒)。当 mutation 的缓存变为未使用或非活跃状态时,该缓存数据将在此时长后被垃圾回收。若指定了不同的缓存时间,将使用最长的时间。
+ - 设置为 `Infinity` 将禁用垃圾回收
+ - 注意:最大允许时间约为 24 天。详见[更多](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#maximum_delay_value)。
+- `mutationKey: unknown[]`
+ - 可选
+ - 可设置 mutation key 以继承通过 `queryClient.setMutationDefaults` 设置的默认值
+- `networkMode: 'online' | 'always' | 'offlineFirst'`
+ - 可选
+ - 默认为 `'online'`
+ - 详见[网络模式](../guides/network-mode.md)
+- `onMutate: (variables: TVariables) => Promise | TContext | void`
+ - 可选
+ - 该函数会在 mutation 函数触发前执行,并接收与 mutation 函数相同的变量
+ - 适用于对资源执行乐观更新,期望 mutation 成功
+ - 该函数返回的值将在 mutation 失败时传递给 `onError` 和 `onSettled` 函数,可用于回滚乐观更新
+- `onSuccess: (data: TData, variables: TVariables, context: TContext) => Promise | unknown`
+ - 可选
+ - 该函数会在 mutation 成功时触发,并接收 mutation 的结果
+ - 若返回 Promise,将在继续前等待其解析
+- `onError: (err: TError, variables: TVariables, context?: TContext) => Promise | unknown`
+ - 可选
+ - 该函数会在 mutation 遇到错误时触发,并接收错误信息
+ - 若返回 Promise,将在继续前等待其解析
+- `onSettled: (data: TData, error: TError, variables: TVariables, context?: TContext) => Promise | unknown`
+ - 可选
+ - 该函数会在 mutation 成功获取或遇到错误时触发,并接收数据或错误信息
+ - 若返回 Promise,将在继续前等待其解析
+- `retry: boolean | number | (failureCount: number, error: TError) => boolean`
+ - 默认为 `0`
+ - 若为 `false`,失败的 mutation 不会重试
+ - 若为 `true`,失败的 mutation 会无限重试
+ - 若设为数字(如 `3`),失败的 mutation 会重试直到失败次数达到该数字
+- `retryDelay: number | (retryAttempt: number, error: TError) => number`
+ - 该函数接收 `retryAttempt` 整数和实际错误,返回下一次尝试前的延迟时间(毫秒)
+ - 如 `attempt => Math.min(attempt > 1 ? 2 ** attempt * 1000 : 1000, 30 * 1000)` 这样的函数会应用指数退避
+ - 如 `attempt => attempt * 1000` 这样的函数会应用线性退避
+- `scope: { id: string }`
+ - 可选
+ - 默认为唯一 ID(因此所有 mutation 并行运行)
+ - 具有相同 scope ID 的 mutation 会串行执行
+- `throwOnError: undefined | boolean | (error: TError) => boolean`
+ - 设为 `true` 时,mutation 错误会在渲染阶段抛出并传播到最近的错误边界
+ - 设为 `false` 时,禁用向错误边界抛出错误的行为
+ - 若设为函数,将接收错误并返回布尔值,指示是否在错误边界显示错误(`true`)或将其作为状态返回(`false`)
+- `meta: Record`
+ - 可选
+ - 若设置,会在 mutation 缓存条目上存储额外信息,可在需要时使用。该信息在 `mutation` 可用的任何地方都可访问(如 `MutationCache` 的 `onError`、`onSuccess` 函数)
+
+**参数2 (QueryClient)**
+
+- `queryClient?: QueryClient`
+ - 用于指定自定义的 QueryClient。若未提供,则使用最近上下文中的 QueryClient
+
+**返回值**
+
+- `mutate: (variables: TVariables, { onSuccess, onSettled, onError }) => void`
+ - 可调用的 mutation 函数,传入变量以触发 mutation,并可选择性地挂钩到额外的回调选项
+ - `variables: TVariables`
+ - 可选
+ - 传递给 `mutationFn` 的变量对象
+ - `onSuccess: (data: TData, variables: TVariables, context: TContext) => void`
+ - 可选
+ - 该函数会在 mutation 成功时触发,并接收 mutation 的结果
+ - 无返回值,返回的值将被忽略
+ - `onError: (err: TError, variables: TVariables, context: TContext | undefined) => void`
+ - 可选
+ - 该函数会在 mutation 遇到错误时触发,并接收错误信息
+ - 无返回值,返回的值将被忽略
+ - `onSettled: (data: TData | undefined, error: TError | null, variables: TVariables, context: TContext | undefined) => void`
+ - 可选
+ - 该函数会在 mutation 成功获取或遇到错误时触发,并接收数据或错误信息
+ - 无返回值,返回的值将被忽略
+ - 若发起多次请求,`onSuccess` 只会在最后一次调用后触发
+- `mutateAsync: (variables: TVariables, { onSuccess, onSettled, onError }) => Promise`
+ - 类似于 `mutate`,但返回可被 await 的 Promise
+- `status: string`
+ - 可能的值:
+ - `idle`:mutation 函数执行前的初始状态
+ - `pending`:mutation 正在执行
+ - `error`:最后一次 mutation 尝试导致错误
+ - `success`:最后一次 mutation 尝试成功
+- `isIdle`、`isPending`、`isSuccess`、`isError`:从 `status` 派生的布尔变量
+- `isPaused: boolean`
+ - 若 mutation 被 `paused`,则为 `true`
+ - 详见[网络模式](../guides/network-mode.md)
+- `data: undefined | unknown`
+ - 默认为 `undefined`
+ - mutation 最后一次成功解析的数据
+- `error: null | TError`
+ - 查询的错误对象(若遇到错误)
+- `reset: () => void`
+ - 清理 mutation 内部状态的函数(即将其重置为初始状态)
+- `failureCount: number`
+ - mutation 的失败计数
+ - 每次 mutation 失败时递增
+ - mutation 成功时重置为 `0`
+- `failureReason: null | TError`
+ - mutation 重试的失败原因
+ - mutation 成功时重置为 `null`
+- `submittedAt: number`
+ - mutation 提交时的时间戳
+ - 默认为 `0`
+- `variables: undefined | TVariables`
+ - 传递给 `mutationFn` 的 `variables` 对象
+ - 默认为 `undefined`
diff --git a/docs/zh-hans/framework/react/reference/useMutationState.md b/docs/zh-hans/framework/react/reference/useMutationState.md
new file mode 100644
index 00000000000..9187d3a975f
--- /dev/null
+++ b/docs/zh-hans/framework/react/reference/useMutationState.md
@@ -0,0 +1,83 @@
+---
+source-updated-at: '2025-03-18T08:45:11.000Z'
+translation-updated-at: '2025-05-06T04:37:20.212Z'
+id: useMutationState
+title: useMutationState
+---
+
+`useMutationState` 是一个钩子函数,用于访问 `MutationCache` 中的所有变更 (mutation) 状态。你可以通过传递 `filters` 参数来筛选变更,并通过 `select` 参数转换变更状态。
+
+**示例 1:获取所有进行中变更的变量**
+
+```tsx
+import { useMutationState } from '@tanstack/react-query'
+
+const variables = useMutationState({
+ filters: { status: 'pending' },
+ select: (mutation) => mutation.state.variables,
+})
+```
+
+**示例 2:通过 `mutationKey` 获取特定变更的所有数据**
+
+```tsx
+import { useMutation, useMutationState } from '@tanstack/react-query'
+
+const mutationKey = ['posts']
+
+// 我们需要获取状态的某个变更
+const mutation = useMutation({
+ mutationKey,
+ mutationFn: (newPost) => {
+ return axios.post('/posts', newPost)
+ },
+})
+
+const data = useMutationState({
+ // 此变更键需与目标变更的键匹配(见上文)
+ filters: { mutationKey },
+ select: (mutation) => mutation.state.data,
+})
+```
+
+**示例 3:通过 `mutationKey` 访问最新的变更数据**
+每次调用 `mutate` 都会在变更缓存中添加一个新条目,持续 `gcTime` 毫秒。
+
+要访问最新的调用,可以检查 `useMutationState` 返回的最后一个条目。
+
+```tsx
+import { useMutation, useMutationState } from '@tanstack/react-query'
+
+const mutationKey = ['posts']
+
+// 我们需要获取状态的某个变更
+const mutation = useMutation({
+ mutationKey,
+ mutationFn: (newPost) => {
+ return axios.post('/posts', newPost)
+ },
+})
+
+const data = useMutationState({
+ // 此变更键需与目标变更的键匹配(见上文)
+ filters: { mutationKey },
+ select: (mutation) => mutation.state.data,
+})
+
+// 最新的变更数据
+const latest = data[data.length - 1]
+```
+
+**配置项**
+
+- `options`
+ - `filters?: MutationFilters`: [变更过滤器](../guides/filters.md#mutation-filters)
+ - `select?: (mutation: Mutation) => TResult`
+ - 用于转换变更状态。
+- `queryClient?: QueryClient`,
+ - 用于指定自定义的 QueryClient。若不提供,则使用最近上下文中的实例。
+
+**返回值**
+
+- `Array`
+ - 返回由 `select` 函数处理后的匹配变更结果数组。
diff --git a/docs/zh-hans/framework/react/reference/usePrefetchInfiniteQuery.md b/docs/zh-hans/framework/react/reference/usePrefetchInfiniteQuery.md
new file mode 100644
index 00000000000..c2cc95b8dd3
--- /dev/null
+++ b/docs/zh-hans/framework/react/reference/usePrefetchInfiniteQuery.md
@@ -0,0 +1,39 @@
+---
+source-updated-at: '2025-03-18T08:45:11.000Z'
+translation-updated-at: '2025-05-06T04:36:52.114Z'
+id: usePrefetchInfiniteQuery
+title: usePrefetchInfiniteQuery
+---
+
+```tsx
+usePrefetchInfiniteQuery(options)
+```
+
+**选项**
+
+你可以向 `usePrefetchInfiniteQuery` 传递所有 [`queryClient.prefetchInfiniteQuery`](../../../reference/QueryClient.md#queryclientprefetchinfinitequery) 支持的参数。请注意以下必填项:
+
+- `queryKey: QueryKey`
+
+ - **必填**
+ - 用于在渲染期间预取的查询键 (query key)
+
+- `queryFn: (context: QueryFunctionContext) => Promise`
+
+ - **必填(但仅在未定义默认查询函数时)** 更多信息请参阅 [默认查询函数](../guides/default-query-function.md)
+
+- `initialPageParam: TPageParam`
+
+ - **必填**
+ - 获取第一页时使用的默认页面参数 (page param)
+
+- `getNextPageParam: (lastPage, allPages, lastPageParam, allPageParams) => TPageParam | undefined | null`
+
+ - **必填**
+ - 当接收到该查询的新数据时,此函数会接收无限数据列表的最后一页、所有页面的完整数组以及页面参数信息
+ - 它应返回**单个变量**,该变量将作为最后一个可选参数传递给查询函数
+ - 返回 `undefined` 或 `null` 表示没有可用的下一页
+
+- **返回值**
+
+`usePrefetchInfiniteQuery` 不返回任何内容,它仅用于在渲染期间(在包裹了使用 [`useSuspenseInfiniteQuery`](../reference/useSuspenseInfiniteQuery.md) 的组件的 Suspense 边界之前)触发预取
diff --git a/docs/zh-hans/framework/react/reference/usePrefetchQuery.md b/docs/zh-hans/framework/react/reference/usePrefetchQuery.md
new file mode 100644
index 00000000000..a05fb5baeaf
--- /dev/null
+++ b/docs/zh-hans/framework/react/reference/usePrefetchQuery.md
@@ -0,0 +1,26 @@
+---
+source-updated-at: '2025-03-18T08:45:11.000Z'
+translation-updated-at: '2025-05-06T04:36:32.898Z'
+id: usePrefetchQuery
+title: usePrefetchQuery
+---
+
+```tsx
+usePrefetchQuery(options)
+```
+
+**选项**
+
+你可以向 `usePrefetchQuery` 传递所有 [`queryClient.prefetchQuery`](../../../reference/QueryClient.md#queryclientprefetchquery) 支持的参数。请注意以下必填项:
+
+- `queryKey: QueryKey`
+
+ - **必填**
+ - 需要在渲染期间预取的查询键 (query key)
+
+- `queryFn: (context: QueryFunctionContext) => Promise`
+ - **必填(但仅在未定义默认查询函数时适用)** 更多信息请参阅 [默认查询函数](../guides/default-query-function.md)
+
+**返回值**
+
+`usePrefetchQuery` 不返回任何值,其用途仅是在渲染期间触发预取操作,通常用于包裹 [`useSuspenseQuery`](../reference/useSuspenseQuery.md) 组件的 suspense 边界之前执行。
diff --git a/docs/zh-hans/framework/react/reference/useQueries.md b/docs/zh-hans/framework/react/reference/useQueries.md
new file mode 100644
index 00000000000..0569dd77f71
--- /dev/null
+++ b/docs/zh-hans/framework/react/reference/useQueries.md
@@ -0,0 +1,69 @@
+---
+source-updated-at: '2025-03-18T08:45:11.000Z'
+translation-updated-at: '2025-05-06T04:36:21.202Z'
+id: useQueries
+title: useQueries
+---
+
+`useQueries` 钩子可用于获取可变数量的查询:
+
+```tsx
+const ids = [1, 2, 3]
+const results = useQueries({
+ queries: ids.map((id) => ({
+ queryKey: ['post', id],
+ queryFn: () => fetchPost(id),
+ staleTime: Infinity,
+ })),
+})
+```
+
+**选项**
+
+`useQueries` 钩子接收一个配置对象,其中 **queries** 键的值是一个数组,数组中的查询配置对象与 [`useQuery` 钩子](../reference/useQuery.md) 完全相同(不包括 `queryClient` 选项 —— 因为 `QueryClient` 可以在顶层传入)。
+
+- `queryClient?: QueryClient`
+ - 用于提供自定义的 QueryClient。否则会使用最近上下文中的实例。
+- `combine?: (result: UseQueriesResults) => TCombinedResult`
+ - 用于将多个查询结果合并为单个值。
+
+> 在查询对象数组中多次使用相同的查询键可能导致查询间共享数据。为避免这种情况,建议对查询进行去重,并将结果映射回所需结构。
+
+**placeholderData**
+
+`useQueries` 同样支持 `placeholderData` 选项,但由于 `useQueries` 的输入可能在每次渲染时具有不同数量的查询,因此它不会像 `useQuery` 那样从先前渲染的查询中获取信息。
+
+**返回值**
+
+`useQueries` 钩子返回一个包含所有查询结果的数组,返回顺序与输入顺序一致。
+
+## 合并结果
+
+若需要将结果中的 `data`(或其他查询信息)合并为单个值,可以使用 `combine` 选项。合并结果会通过结构共享尽可能保持引用稳定。
+
+```tsx
+const ids = [1, 2, 3]
+const combinedQueries = useQueries({
+ queries: ids.map((id) => ({
+ queryKey: ['post', id],
+ queryFn: () => fetchPost(id),
+ })),
+ combine: (results) => {
+ return {
+ data: results.map((result) => result.data),
+ pending: results.some((result) => result.isPending),
+ }
+ },
+})
+```
+
+上例中,`combinedQueries` 将是一个包含 `data` 和 `pending` 属性的对象。注意查询结果的其他属性会被丢弃。
+
+### 记忆化
+
+`combine` 函数仅在以下情况下重新执行:
+
+- `combine` 函数本身的引用发生变化
+- 任意查询结果发生变化
+
+这意味着如上所示的内联 `combine` 函数会在每次渲染时运行。为避免这种情况,可以用 `useCallback` 包裹 `combine` 函数,或将其提取为无依赖的稳定函数引用。
diff --git a/docs/zh-hans/framework/react/reference/useQuery.md b/docs/zh-hans/framework/react/reference/useQuery.md
new file mode 100644
index 00000000000..e1c038c5b53
--- /dev/null
+++ b/docs/zh-hans/framework/react/reference/useQuery.md
@@ -0,0 +1,256 @@
+---
+source-updated-at: '2025-03-18T08:45:11.000Z'
+translation-updated-at: '2025-05-06T04:35:52.836Z'
+id: useQuery
+title: useQuery
+---
+
+```tsx
+const {
+ data,
+ dataUpdatedAt,
+ error,
+ errorUpdatedAt,
+ failureCount,
+ failureReason,
+ fetchStatus,
+ isError,
+ isFetched,
+ isFetchedAfterMount,
+ isFetching,
+ isInitialLoading,
+ isLoading,
+ isLoadingError,
+ isPaused,
+ isPending,
+ isPlaceholderData,
+ isRefetchError,
+ isRefetching,
+ isStale,
+ isSuccess,
+ promise,
+ refetch,
+ status,
+} = useQuery(
+ {
+ queryKey,
+ queryFn,
+ gcTime,
+ enabled,
+ networkMode,
+ initialData,
+ initialDataUpdatedAt,
+ meta,
+ notifyOnChangeProps,
+ placeholderData,
+ queryKeyHashFn,
+ refetchInterval,
+ refetchIntervalInBackground,
+ refetchOnMount,
+ refetchOnReconnect,
+ refetchOnWindowFocus,
+ retry,
+ retryOnMount,
+ retryDelay,
+ select,
+ staleTime,
+ structuralSharing,
+ subscribed,
+ throwOnError,
+ },
+ queryClient,
+)
+```
+
+**参数1 (配置项)**
+
+- `queryKey: unknown[]`
+ - **必填**
+ - 用于此查询的查询键 (query key)。
+ - 查询键会被哈希成一个稳定的哈希值。详见 [查询键](../guides/query-keys.md)。
+ - 当此键发生变化时,查询会自动更新(只要 `enabled` 未设为 `false`)。
+- `queryFn: (context: QueryFunctionContext) => Promise`
+ - **必填,但仅在未定义默认查询函数时** 详见 [默认查询函数](../guides/default-query-function.md)。
+ - 查询用于请求数据的函数。
+ - 接收一个 [QueryFunctionContext](../guides/query-functions.md#queryfunctioncontext)。
+ - 必须返回一个会解析数据或抛出错误的 Promise。数据不能为 `undefined`。
+- `enabled: boolean | (query: Query) => boolean`
+ - 设为 `false` 可禁用此查询自动运行。
+ - 可用于 [依赖查询](../guides/dependent-queries.md)。
+- `networkMode: 'online' | 'always' | 'offlineFirst`
+ - 可选
+ - 默认为 `'online'`
+ - 详见 [网络模式](../guides/network-mode.md)。
+- `retry: boolean | number | (failureCount: number, error: TError) => boolean`
+ - 如果为 `false`,默认情况下失败的查询不会重试。
+ - 如果为 `true`,失败的查询会无限重试。
+ - 如果设为数字(如 `3`),失败的查询会重试直到失败次数达到该数字。
+ - 客户端默认为 `3`,服务端默认为 `0`。
+- `retryOnMount: boolean`
+ - 如果设为 `false`,当查询包含错误时不会在挂载时重试。默认为 `true`。
+- `retryDelay: number | (retryAttempt: number, error: TError) => number`
+ - 此函数接收 `retryAttempt` 整数和实际的 Error,并返回下一次尝试前的延迟时间(毫秒)。
+ - 像 `attempt => Math.min(attempt > 1 ? 2 ** attempt * 1000 : 1000, 30 * 1000)` 这样的函数会应用指数退避。
+ - 像 `attempt => attempt * 1000` 这样的函数会应用线性退避。
+- `staleTime: number | ((query: Query) => number)`
+ - 可选
+ - 默认为 `0`
+ - 数据被视为过时的时间(毫秒)。此值仅适用于定义它的钩子。
+ - 如果设为 `Infinity`,数据永远不会被视为过时。
+ - 如果设为函数,该函数会接收查询并计算 `staleTime`。
+- `gcTime: number | Infinity`
+ - 默认为 `5 * 60 * 1000`(5 分钟)或在 SSR 期间为 `Infinity`
+ - 未使用/非活跃的缓存数据在内存中保留的时间(毫秒)。当查询的缓存变为未使用或非活跃时,该缓存数据会在此时间后被垃圾回收。如果指定了不同的垃圾回收时间,将使用最长的时间。
+ - 注意:最大允许时间约为 24 天。详见 [更多](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#maximum_delay_value)。
+ - 如果设为 `Infinity`,会禁用垃圾回收。
+- `queryKeyHashFn: (queryKey: QueryKey) => string`
+ - 可选
+ - 如果指定,此函数用于将 `queryKey` 哈希为字符串。
+- `refetchInterval: number | false | ((query: Query) => number | false | undefined)`
+ - 可选
+ - 如果设为数字,所有查询会按此频率(毫秒)持续重新获取。
+ - 如果设为函数,该函数会接收查询并计算频率。
+- `refetchIntervalInBackground: boolean`
+ - 可选
+ - 如果设为 `true`,设置为持续重新获取的查询会在其标签页/窗口处于后台时继续重新获取。
+- `refetchOnMount: boolean | "always" | ((query: Query) => boolean | "always")`
+ - 可选
+ - 默认为 `true`
+ - 如果设为 `true`,当数据过时会在挂载时重新获取。
+ - 如果设为 `false`,不会在挂载时重新获取。
+ - 如果设为 `"always"`,会在挂载时始终重新获取。
+ - 如果设为函数,该函数会接收查询并计算值。
+- `refetchOnWindowFocus: boolean | "always" | ((query: Query) => boolean | "always")`
+ - 可选
+ - 默认为 `true`
+ - 如果设为 `true`,当数据过时会在窗口获得焦点时重新获取。
+ - 如果设为 `false`,不会在窗口获得焦点时重新获取。
+ - 如果设为 `"always"`,会在窗口获得焦点时始终重新获取。
+ - 如果设为函数,该函数会接收查询并计算值。
+- `refetchOnReconnect: boolean | "always" | ((query: Query) => boolean | "always")`
+ - 可选
+ - 默认为 `true`
+ - 如果设为 `true`,当数据过时会在重新连接时重新获取。
+ - 如果设为 `false`,不会在重新连接时重新获取。
+ - 如果设为 `"always"`,会在重新连接时始终重新获取。
+ - 如果设为函数,该函数会接收查询并计算值。
+- `notifyOnChangeProps: string[] | "all" | (() => string[] | "all" | undefined)`
+ - 可选
+ - 如果设置,组件只会在列出的属性变化时重新渲染。
+ - 例如设为 `['data', 'error']`,组件只会在 `data` 或 `error` 属性变化时重新渲染。
+ - 如果设为 `"all"`,组件会退出智能跟踪,并在查询更新时始终重新渲染。
+ - 如果设为函数,该函数会执行以计算属性列表。
+ - 默认情况下,会跟踪属性访问,组件只会在跟踪的属性变化时重新渲染。
+- `select: (data: TData) => unknown`
+ - 可选
+ - 此选项可用于转换或选择查询函数返回数据的一部分。它影响返回的 `data` 值,但不影响查询缓存中存储的内容。
+ - `select` 函数只会在 `data` 变化或 `select` 函数本身的引用变化时运行。为了优化,可以用 `useCallback` 包裹函数。
+- `initialData: TData | () => TData`
+ - 可选
+ - 如果设置,此值会用作查询缓存的初始数据(只要查询尚未创建或缓存)。
+ - 如果设为函数,该函数会在共享/根查询初始化期间调用**一次**,并应同步返回初始数据。
+ - 初始数据默认被视为过时,除非设置了 `staleTime`。
+ - `initialData` **会持久化**到缓存。
+- `initialDataUpdatedAt: number | (() => number | undefined)`
+ - 可选
+ - 如果设置,此值会用作 `initialData` 本身最后更新的时间(毫秒)。
+- `placeholderData: TData | (previousValue: TData | undefined; previousQuery: Query | undefined,) => TData`
+ - 可选
+ - 如果设置,此值会用作此特定查询观察器的占位数据,当查询仍处于 `pending` 状态时。
+ - `placeholderData` **不会持久化**到缓存。
+ - 如果为 `placeholderData` 提供函数,第一个参数会接收之前观察的查询数据(如果可用),第二个参数是完整的 previousQuery 实例。
+- `structuralSharing: boolean | (oldData: unknown | undefined, newData: unknown) => unknown)`
+ - 可选
+ - 默认为 `true`
+ - 如果设为 `false`,会禁用查询结果之间的结构共享。
+ - 如果设为函数,旧数据和新数据会通过此函数传递,该函数应将它们组合为查询的解析数据。这样,即使数据包含不可序列化的值,也可以保留旧数据的引用以提高性能。
+- `subscribed: boolean`
+ - 可选
+ - 默认为 `true`
+ - 如果设为 `false`,此 `useQuery` 实例不会订阅缓存。这意味着它不会自行触发 `queryFn`,也不会在数据通过其他方式进入缓存时接收更新。
+- `throwOnError: undefined | boolean | (error: TError, query: Query) => boolean`
+ - 设为 `true` 时,错误会在渲染阶段抛出并传播到最近的错误边界。
+ - 设为 `false` 可禁用 `suspense` 将错误抛出到错误边界的默认行为。
+ - 如果设为函数,会传入错误和查询,并应返回布尔值,指示是否在错误边界中显示错误(`true`)或将错误作为状态返回(`false`)。
+- `meta: Record`
+ - 可选
+ - 如果设置,会在查询缓存条目上存储额外的信息,可根据需要使用。在 `query` 可访问的任何地方都可以访问它,也是提供给 `queryFn` 的 `QueryFunctionContext` 的一部分。
+
+**参数2 (QueryClient)**
+
+- `queryClient?: QueryClient`,
+ - 使用此参数可自定义 QueryClient。否则会使用最近上下文中的 QueryClient。
+
+**返回值**
+
+- `status: QueryStatus`
+ - 可能为:
+ - `pending`:如果无缓存数据且查询尝试尚未完成。
+ - `error`:如果查询尝试导致错误。对应的 `error` 属性包含从尝试获取中接收的错误。
+ - `success`:如果查询接收到无错误的响应并准备显示其数据。查询的 `data` 属性是从成功获取中接收的数据,或者如果查询的 `enabled` 属性设为 `false` 且尚未获取,`data` 是初始化时提供给查询的第一个 `initialData`。
+- `isPending: boolean`
+ - 从上述 `status` 变量派生的布尔值,为方便提供。
+- `isSuccess: boolean`
+ - 从上述 `status` 变量派生的布尔值,为方便提供。
+- `isError: boolean`
+ - 从上述 `status` 变量派生的布尔值,为方便提供。
+- `isLoadingError: boolean`
+ - 如果查询在首次获取时失败则为 `true`。
+- `isRefetchError: boolean`
+ - 如果查询在重新获取时失败则为 `true`。
+- `data: TData`
+ - 默认为 `undefined`。
+ - 查询最后成功解析的数据。
+- `dataUpdatedAt: number`
+ - 查询最近返回 `status` 为 `"success"` 时的时间戳。
+- `error: null | TError`
+ - 默认为 `null`
+ - 查询的错误对象,如果抛出错误。
+- `errorUpdatedAt: number`
+ - 查询最近返回 `status` 为 `"error"` 时的时间戳。
+- `isStale: boolean`
+ - 如果缓存中的数据无效或数据比给定的 `staleTime` 旧则为 `true`。
+- `isPlaceholderData: boolean`
+ - 如果显示的数据是占位数据则为 `true`。
+- `isFetched: boolean`
+ - 如果查询已获取则为 `true`。
+- `isFetchedAfterMount: boolean`
+ - 如果查询在组件挂载后已获取则为 `true`。
+ - 此属性可用于不显示任何先前缓存的数据。
+- `fetchStatus: FetchStatus`
+ - `fetching`:当 `queryFn` 正在执行时为 `true`,包括初始 `pending` 和后台重新获取。
+ - `paused`:查询想要获取,但已被 `paused`。
+ - `idle`:查询未在获取。
+ - 详见 [网络模式](../guides/network-mode)。
+- `isFetching: boolean`
+ - 从上述 `fetchStatus` 变量派生的布尔值,为方便提供。
+- `isPaused: boolean`
+ - 从上述 `fetchStatus` 变量派生的布尔值,为方便提供。
+- `isRefetching: boolean`
+ - 当后台重新获取进行中时为 `true`,**不包括**初始 `pending`。
+ - 等同于 `isFetching && !isPending`。
+- `isLoading: boolean`
+ - 当查询首次获取进行中时为 `true`。
+ - 等同于 `isFetching && isPending`。
+- `isInitialLoading: boolean`
+ - **已弃用**
+ - `isLoading` 的别名,将在下一个主版本中移除。
+- `failureCount: number`
+ - 查询的失败次数。
+ - 每次查询失败时递增。
+ - 查询成功时重置为 `0`。
+- `failureReason: null | TError`
+ - 查询重试的失败原因。
+ - 查询成功时重置为 `null`。
+- `errorUpdateCount: number`
+ - 所有错误的总和。
+- `refetch: (options: { throwOnError: boolean, cancelRefetch: boolean }) => Promise`
+ - 手动重新获取查询的函数。
+ - 如果查询出错,错误只会被记录。如果想抛出错误,传递 `throwOnError: true` 选项。
+ - `cancelRefetch?: boolean`
+ - 默认为 `true`
+ - 默认情况下,新请求发出前会取消当前正在运行的请求。
+ - 设为 `false` 时,如果已有请求运行则不会重新获取。
+- `promise: Promise`
+ - 一个稳定的 Promise,会解析为查询的数据。
+ - 需要在 `QueryClient` 上启用 `experimental_prefetchInRender` 特性标志。
diff --git a/docs/zh-hans/framework/react/reference/useQueryClient.md b/docs/zh-hans/framework/react/reference/useQueryClient.md
new file mode 100644
index 00000000000..8120a0283bc
--- /dev/null
+++ b/docs/zh-hans/framework/react/reference/useQueryClient.md
@@ -0,0 +1,19 @@
+---
+source-updated-at: '2024-01-25T20:57:22.000Z'
+translation-updated-at: '2025-05-06T04:33:32.399Z'
+id: useQueryClient
+title: useQueryClient
+---
+
+`useQueryClient` 钩子返回当前的 `QueryClient` 实例。
+
+```tsx
+import { useQueryClient } from '@tanstack/react-query'
+
+const queryClient = useQueryClient(queryClient?: QueryClient)
+```
+
+**选项**
+
+- `queryClient?: QueryClient`,
+ - 用于指定自定义的 QueryClient。若未提供,则使用最近上下文中的 QueryClient。
diff --git a/docs/zh-hans/framework/react/reference/useQueryErrorResetBoundary.md b/docs/zh-hans/framework/react/reference/useQueryErrorResetBoundary.md
new file mode 100644
index 00000000000..253c71a5df6
--- /dev/null
+++ b/docs/zh-hans/framework/react/reference/useQueryErrorResetBoundary.md
@@ -0,0 +1,30 @@
+---
+source-updated-at: '2024-04-11T09:16:39.000Z'
+translation-updated-at: '2025-05-06T04:33:21.777Z'
+id: useQueryErrorResetBoundary
+title: useQueryErrorResetBoundary
+---
+
+该钩子函数会重置最近一层 `QueryErrorResetBoundary` 内的所有查询错误。如果未定义边界,则会全局重置错误:
+
+```tsx
+import { useQueryErrorResetBoundary } from '@tanstack/react-query'
+import { ErrorBoundary } from 'react-error-boundary'
+
+const App = () => {
+ const { reset } = useQueryErrorResetBoundary()
+ return (
+ (
+
+ 发生错误!
+ resetErrorBoundary()}>重试
+
+ )}
+ >
+
+
+ )
+}
+```
diff --git a/docs/zh-hans/framework/react/reference/useSuspenseInfiniteQuery.md b/docs/zh-hans/framework/react/reference/useSuspenseInfiniteQuery.md
new file mode 100644
index 00000000000..280c32e0942
--- /dev/null
+++ b/docs/zh-hans/framework/react/reference/useSuspenseInfiniteQuery.md
@@ -0,0 +1,32 @@
+---
+source-updated-at: '2025-03-31T09:10:17.000Z'
+translation-updated-at: '2025-05-06T04:33:11.338Z'
+id: useSuspenseInfiniteQuery
+title: useSuspenseInfiniteQuery
+---
+
+```tsx
+const result = useSuspenseInfiniteQuery(options)
+```
+
+**配置项**
+
+与 [useInfiniteQuery](../reference/useInfiniteQuery.md) 相同,但以下选项除外:
+
+- `suspense`
+- `throwOnError`
+- `enabled`
+- `placeholderData`
+
+**返回值**
+
+返回对象与 [useInfiniteQuery](../reference/useInfiniteQuery.md) 相同,但存在以下差异:
+
+- `data` 保证已定义
+- 不存在 `isPlaceholderData` 属性
+- `status` 始终为 `success`
+ - 派生的状态标志会相应设置
+
+**注意事项**
+
+[取消查询](../guides/query-cancellation.md) 功能不可用。
diff --git a/docs/zh-hans/framework/react/reference/useSuspenseQueries.md b/docs/zh-hans/framework/react/reference/useSuspenseQueries.md
new file mode 100644
index 00000000000..3a7808b10fa
--- /dev/null
+++ b/docs/zh-hans/framework/react/reference/useSuspenseQueries.md
@@ -0,0 +1,34 @@
+---
+source-updated-at: '2025-03-31T09:10:17.000Z'
+translation-updated-at: '2025-05-06T04:27:49.567Z'
+id: useSuspenseQueries
+title: useSuspenseQueries
+---
+
+```tsx
+const result = useSuspenseQueries(options)
+```
+
+**参数选项**
+
+与 [useQueries](../reference/useQueries.md) 相同,但每个 `query` 不能包含以下属性:
+
+- `suspense`
+- `throwOnError`
+- `enabled`
+- `placeholderData`
+
+**返回值**
+
+返回结构与 [useQueries](../reference/useQueries.md) 相同,但针对每个 `query` 有以下区别:
+
+- `data` 保证已定义
+- 不包含 `isPlaceholderData` 属性
+- `status` 始终为 `success`
+ - 派生的状态标志也会相应设置
+
+**注意事项**
+
+请注意组件只会在**所有查询**完成加载后重新挂载。因此,如果在所有查询完成期间某个查询已过期,重新挂载时会再次发起请求。为避免此问题,请确保设置足够长的 `staleTime`。
+
+[取消查询](../guides/query-cancellation.md) 功能不可用。
diff --git a/docs/zh-hans/framework/react/reference/useSuspenseQuery.md b/docs/zh-hans/framework/react/reference/useSuspenseQuery.md
new file mode 100644
index 00000000000..a071a7cc855
--- /dev/null
+++ b/docs/zh-hans/framework/react/reference/useSuspenseQuery.md
@@ -0,0 +1,31 @@
+---
+source-updated-at: '2025-03-31T09:10:17.000Z'
+translation-updated-at: '2025-05-06T04:33:00.266Z'
+id: useSuspenseQuery
+title: useSuspenseQuery
+---
+
+```tsx
+const result = useSuspenseQuery(options)
+```
+
+**参数选项**
+
+与 [useQuery](../reference/useQuery.md) 相同,但以下参数除外:
+
+- `throwOnError`
+- `enabled`
+- `placeholderData`
+
+**返回值**
+
+返回对象与 [useQuery](../reference/useQuery.md) 相同,但存在以下差异:
+
+- `data` 保证已定义(非 undefined)
+- 不包含 `isPlaceholderData` 字段
+- `status` 始终为 `success` 状态
+ - 所有衍生标志位会相应设置
+
+**注意事项**
+
+[查询取消 (Cancellation)](../guides/query-cancellation.md) 功能不可用
diff --git a/docs/zh-hans/framework/react/typescript.md b/docs/zh-hans/framework/react/typescript.md
new file mode 100644
index 00000000000..0058b8f689d
--- /dev/null
+++ b/docs/zh-hans/framework/react/typescript.md
@@ -0,0 +1,252 @@
+---
+source-updated-at: '2025-03-18T08:45:11.000Z'
+translation-updated-at: '2025-05-06T04:29:57.696Z'
+id: typescript
+title: TypeScript
+---
+
+React Query 现已采用 **TypeScript** 编写,确保库与您的项目具备类型安全!
+
+注意事项:
+
+- 当前类型系统要求使用 TypeScript **v4.7** 或更高版本
+- 本仓库中的类型变更被视为**非破坏性变更**,通常以 **patch** 版本号发布(否则每个类型增强都会导致主版本号变更!)
+- **强烈建议您将 react-query 包版本锁定到特定 patch 版本,并在升级时做好类型可能在任何版本间被修复或升级的准备**
+- React Query 中与类型无关的公共 API 仍严格遵循语义化版本规范。
+
+## 类型推断
+
+React Query 中的类型通常能很好地流动,因此您通常无需自行添加类型注解
+
+[//]: # 'TypeInference1'
+
+```tsx
+const { data } = useQuery({
+ // ^? const data: number | undefined
+ queryKey: ['test'],
+ queryFn: () => Promise.resolve(5),
+})
+```
+
+[typescript playground](https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBAbzgVwM4FMCKz1QJ5wC+cAZlBCHAORToCGAxjALQCOO+VAsAFC8MQAdqnhIAJnRh0icALwoM2XHgAUAbSqDkIAEa4qAXQA0cFQEo5APjgAFciGAYAdLVQQANgDd0KgKxmzXgB6ILgw8IA9AH5eIA)
+
+[//]: # 'TypeInference1'
+[//]: # 'TypeInference2'
+
+```tsx
+const { data } = useQuery({
+ // ^? const data: string | undefined
+ queryKey: ['test'],
+ queryFn: () => Promise.resolve(5),
+ select: (data) => data.toString(),
+})
+```
+
+[typescript playground](https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBAbzgVwM4FMCKz1QJ5wC+cAZlBCHAORToCGAxjALQCOO+VAsAFC8MQAdqnhIAJnRh0icALwoM2XHgAUAbSox0IqgF0ANHBUBKOQD44ABXIhgGAHS1UEADYA3dCoCsxw0gwu6EwAXHASUuZhknT2MBAAyjBQwIIA5iaExrwA9Nlw+QUAegD8vEA)
+
+[//]: # 'TypeInference2'
+
+当您的 `queryFn` 具有明确定义的返回类型时,类型推断效果最佳。请注意大多数数据获取库默认返回 `any` 类型,因此请确保将其提取到具有正确类型的函数中:
+
+[//]: # 'TypeInference3'
+
+```tsx
+const fetchGroups = (): Promise =>
+ axios.get('/groups').then((response) => response.data)
+
+const { data } = useQuery({ queryKey: ['groups'], queryFn: fetchGroups })
+// ^? const data: Group[] | undefined
+```
+
+[typescript playground](https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBAbzgVwM4FMCKz1QJ5wC+cAZlBCHAORToCGAxjALQCOO+VAsAFCiSw4dAB7AIqUuUpURY1Nx68YeMOjgBxcsjBwAvIjjAAJgC44AO2QgARriK9eDCOdTwS6GAwAWmiNon6ABQAlGYAClLAGAA8vtoA2gC6AHx6qbLiAHQA5h6BVAD02Vpg8sGZMF7o5oG0qJAuarqpdQ0YmUZ0MHTBDjxOLvBInd1EeigY2Lh4gfFUxX6lVIkANKQe3nGlvTwFBXAHhwB6APxwA65wI3RmW0lwAD4o5kboJMDm6Ea8QA)
+
+[//]: # 'TypeInference3'
+
+## 类型收窄
+
+React Query 使用 [可辨识联合类型 (discriminated union type)](https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes-func.html#discriminated-unions) 作为查询结果,通过 `status` 字段和派生的状态布尔标志进行区分。这使您能够检查例如 `success` 状态来确保 `data` 已定义:
+
+[//]: # 'TypeNarrowing'
+
+```tsx
+const { data, isSuccess } = useQuery({
+ queryKey: ['test'],
+ queryFn: () => Promise.resolve(5),
+})
+
+if (isSuccess) {
+ data
+ // ^? const data: number
+}
+```
+
+[typescript playground](https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBAbzgVwM4FMCKz1QJ5wC+cAZlBCHAORToCGAxjALQCOO+VAsAFC8MQAdqnhIAJnRh0ANHGCoAysgYN0qVETgBeFBmy48ACgDaVGGphUAurMMBKbQD44ABXIh56AHS1UEADYAbuiGAKx2dry8wCRwhvJKKmqoDgi8cBlwElK8APS5GQB6APy8hLxAA)
+
+[//]: # 'TypeNarrowing'
+
+## 错误字段类型标注
+
+错误类型默认为 `Error`,因为这符合大多数用户的预期。
+
+[//]: # 'TypingError'
+
+```tsx
+const { error } = useQuery({ queryKey: ['groups'], queryFn: fetchGroups })
+// ^? const error: Error
+```
+
+[typescript playground](https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBAbzgVwM4FMCKz1QJ5wC+cAZlBCHAOQACMAhgHaoMDGA1gPRTr2swBaAI458VALAAoUJFhx6AD2ARUpcpSqLlqCZKkw8YdHADi5ZGDgBeRHGAATAFxxGyEACNcRKVNYRm8CToMKwAFmYQFqo2ABQAlM4ACurAGAA8ERYA2gC6AHzWBVoqAHQA5sExVJxl5mA6cSUwoeiMMTyokMzGVgUdXRgl9vQMcT6SfgG2uORQRNYoGNi4eDFZVLWR9VQ5ADSkwWGZ9WOSnJxwl1cAegD8QA)
+
+[//]: # 'TypingError'
+
+如果您想抛出自定义错误,或非 `Error` 类型的对象,可以指定错误字段的类型:
+
+[//]: # 'TypingError2'
+
+```tsx
+const { error } = useQuery(['groups'], fetchGroups)
+// ^? const error: string | null
+```
+
+[//]: # 'TypingError2'
+
+但这样做的缺点是 `useQuery` 的其他泛型参数将无法进行类型推断。通常不建议抛出非 `Error` 类型的对象,因此如果存在子类如 `AxiosError`,可以使用**类型收窄**使错误字段更具体:
+
+[//]: # 'TypingError3'
+
+```tsx
+import axios from 'axios'
+
+const { error } = useQuery({ queryKey: ['groups'], queryFn: fetchGroups })
+// ^? const error: Error | null
+
+if (axios.isAxiosError(error)) {
+ error
+ // ^? const error: AxiosError
+}
+```
+
+[typescript playground](https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBAbzgVwM4FMCKz1QJ5wC+cAZlBCHAOQACMAhgHaoMDGA1gPRTr2swBaAI458VALAAoUJFhx6AD2ARUpcpSqLlqCZKkw8YdHADi5ZGDgBeRHGAATAFxxGyEACNcRKVNYRm8CToMKwAFmYQFqo2ABQAlM4ACurAGAA8ERYA2gC6AHzWBVoqAHQA5sExVJxl5mA6cSUwoeiMMTyokMzGVgUdXRgl9vQMcT6SfgG2uORQRNYoGNi4eDFIIisA0uh4zllUtZH1VDkANHAb+ABijM5BIeF1qoRjkpyccJ9fAHoA-OPAEhwGLFVAlVIAQSUKgAolBZjEZtA4nFEFJPkioOi4O84H8pIQgA)
+
+[//]: # 'TypingError3'
+
+### 注册全局错误类型
+
+TanStack Query v5 允许通过扩展 `Register` 接口来设置全局错误类型,无需在调用处指定泛型参数。这将确保类型推断仍然有效,同时错误字段会是指定的类型:
+
+[//]: # 'RegisterErrorType'
+
+```tsx
+import '@tanstack/react-query'
+
+declare module '@tanstack/react-query' {
+ interface Register {
+ defaultError: AxiosError
+ }
+}
+
+const { error } = useQuery({ queryKey: ['groups'], queryFn: fetchGroups })
+// ^? const error: AxiosError | null
+```
+
+[//]: # 'RegisterErrorType'
+[//]: # 'TypingMeta'
+
+## 元数据 (Meta) 类型标注
+
+### 注册全局元数据类型
+
+与注册 [全局错误类型](#registering-a-global-error) 类似,您也可以注册全局 `Meta` 类型。这确保 [查询](./reference/useQuery.md) 和 [变更](./reference/useMutation.md) 中的可选 `meta` 字段保持一致且类型安全。注意注册的类型必须扩展 `Record`,以保证 `meta` 始终是对象类型。
+
+```ts
+import '@tanstack/react-query'
+
+interface MyMeta extends Record {
+ // 您的元数据类型定义
+}
+
+declare module '@tanstack/react-query' {
+ interface Register {
+ queryMeta: MyMeta
+ mutationMeta: MyMeta
+ }
+}
+```
+
+[//]: # 'TypingMeta'
+[//]: # 'TypingQueryAndMutationKeys'
+
+## 查询与变更键 (Key) 类型标注
+
+### 注册查询与变更键类型
+
+同样类似于注册 [全局错误类型](#registering-a-global-error),您还可以注册全局 `QueryKey` 和 `MutationKey` 类型。这允许您为键提供更多结构,匹配应用程序的层次关系,并在库的所有相关接口中保持类型安全。注意注册的类型必须扩展 `Array` 类型,以确保键仍然是数组形式。
+
+```ts
+import '@tanstack/react-query'
+
+type QueryKey = ['dashboard' | 'marketing', ...ReadonlyArray]
+
+declare module '@tanstack/react-query' {
+ interface Register {
+ queryKey: QueryKey
+ mutationKey: QueryKey
+ }
+}
+```
+
+[//]: # 'TypingQueryAndMutationKeys'
+[//]: # 'TypingQueryOptions'
+
+## 查询选项 (Query Options) 类型标注
+
+如果将查询选项内联到 `useQuery` 中,您将获得自动类型推断。但若需要将查询选项提取到单独函数中以便在 `useQuery` 和 `prefetchQuery` 等场景共享,则会失去类型推断。此时可以使用 `queryOptions` 辅助函数恢复类型推断:
+
+```ts
+import { queryOptions } from '@tanstack/react-query'
+
+function groupOptions() {
+ return queryOptions({
+ queryKey: ['groups'],
+ queryFn: fetchGroups,
+ staleTime: 5 * 1000,
+ })
+}
+
+useQuery(groupOptions())
+queryClient.prefetchQuery(groupOptions())
+```
+
+此外,`queryOptions` 返回的 `queryKey` 知晓关联的 `queryFn`,我们可以利用此类型信息使 `queryClient.getQueryData` 等函数也能感知这些类型:
+
+```ts
+function groupOptions() {
+ return queryOptions({
+ queryKey: ['groups'],
+ queryFn: fetchGroups,
+ staleTime: 5 * 1000,
+ })
+}
+
+const data = queryClient.getQueryData(groupOptions().queryKey)
+// ^? const data: Group[] | undefined
+```
+
+若不使用 `queryOptions`,`data` 的类型将为 `unknown`,除非显式传递泛型参数:
+
+```ts
+const data = queryClient.getQueryData(['groups'])
+```
+
+[//]: # 'TypingQueryOptions'
+[//]: # 'Materials'
+
+## 扩展阅读
+
+关于类型推断的技巧,请参阅社区资源中的 [React Query 与 TypeScript](./community/tkdodos-blog.md#6-react-query-and-typescript)。要了解如何实现最佳类型安全,可阅读 [类型安全的 React Query](./community/tkdodos-blog.md#19-type-safe-react-query)。
+
+[//]: # 'Materials'
+
+## 使用 `skipToken` 实现类型安全的查询禁用
+
+如果使用 TypeScript,可以通过 `skipToken` 禁用查询。这在需要根据条件禁用查询但仍希望保持类型安全时非常有用。更多信息请参阅 [禁用查询](./guides/disabling-queries.md) 指南。
diff --git a/docs/zh-hans/framework/react/videos.md b/docs/zh-hans/framework/react/videos.md
new file mode 100644
index 00000000000..d248b10665d
--- /dev/null
+++ b/docs/zh-hans/framework/react/videos.md
@@ -0,0 +1,73 @@
+---
+source-updated-at: '2024-01-25T20:57:22.000Z'
+translation-updated-at: '2025-05-06T04:26:01.170Z'
+id: videos
+title: 视频与演讲
+---
+
+VIDEO
+
+[点击此处查看上述演示使用的代码仓库](https://github.com/tannerlinsley/react-query-blog-refactor-example)
+
+VIDEO
+
+VIDEO
+
+VIDEO
+
+VIDEO
diff --git a/docs/zh-hans/framework/solid/community/community-projects.md b/docs/zh-hans/framework/solid/community/community-projects.md
new file mode 100644
index 00000000000..9cad75d6eb3
--- /dev/null
+++ b/docs/zh-hans/framework/solid/community/community-projects.md
@@ -0,0 +1,9 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:51.671Z'
+id: community-projects
+title: Community Projects
+ref: docs/zh-hans/framework/react/community/community-projects.md
+replace:
+ React Query: TanStack Query
+---
diff --git a/docs/zh-hans/framework/solid/community/tkdodos-blog.md b/docs/zh-hans/framework/solid/community/tkdodos-blog.md
new file mode 100644
index 00000000000..6aaba916364
--- /dev/null
+++ b/docs/zh-hans/framework/solid/community/tkdodos-blog.md
@@ -0,0 +1,7 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:51.635Z'
+id: tkdodos-blog
+title: TkDodo's Blog
+ref: docs/zh-hans/framework/react/community/tkdodos-blog.md
+---
diff --git a/docs/zh-hans/framework/solid/devtools.md b/docs/zh-hans/framework/solid/devtools.md
new file mode 100644
index 00000000000..5cb754d9085
--- /dev/null
+++ b/docs/zh-hans/framework/solid/devtools.md
@@ -0,0 +1,83 @@
+---
+source-updated-at: '2024-08-21T11:18:15.000Z'
+translation-updated-at: '2025-05-06T05:15:27.103Z'
+id: devtools
+title: 开发者工具
+---
+
+欢呼雀跃吧,因为 Solid Query 配备了专属的开发工具 (Devtools)!🥳
+
+当你开始使用 Solid Query 时,这些开发工具将成为得力助手。它们能直观展示 Solid Query 的内部运作机制,在你遇到棘手问题时,很可能为你节省数小时的调试时间!
+
+## 安装并导入开发工具
+
+开发工具是一个独立包,需单独安装:
+
+```bash
+npm i @tanstack/solid-query-devtools
+```
+
+或
+
+```bash
+pnpm add @tanstack/solid-query-devtools
+```
+
+或
+
+```bash
+yarn add @tanstack/solid-query-devtools
+```
+
+或
+
+```bash
+bun add @tanstack/solid-query-devtools
+```
+
+导入方式如下:
+
+```tsx
+import { SolidQueryDevtools } from '@tanstack/solid-query-devtools'
+```
+
+默认情况下,Solid Query 开发工具仅在 `isServer === true` 时包含在构建包中([`isServer`](https://github.com/solidjs/solid/blob/a72d393a07b22f9b7496e5eb93712188ccce0d28/packages/solid/web/src/index.ts#L37) 来自 `solid-js/web` 包),因此无需担心生产构建时需要手动排除它们。
+
+## 浮动模式
+
+浮动模式会将开发工具作为固定悬浮元素挂载到应用中,并在屏幕角落提供显示/隐藏的切换按钮。该状态会保存在 localStorage 中,即使刷新页面也会被记住。
+
+请将以下代码尽可能放置在 Solid 应用的顶层。越靠近页面根节点,效果越好!
+
+```tsx
+import { SolidQueryDevtools } from '@tanstack/solid-query-devtools'
+
+function App() {
+ return (
+
+ {/* 应用的其他部分 */}
+
+
+ )
+}
+```
+
+### 配置项
+
+- `initialIsOpen: Boolean`
+ - 设为 `true` 可使开发工具默认展开
+- `buttonPosition?: "top-left" | "top-right" | "bottom-left" | "bottom-right"`
+ - 默认为 `bottom-right`
+ - 控制 Solid Query 徽标按钮的位置,用于展开/收起开发工具面板
+- `position?: "top" | "bottom" | "left" | "right"`
+ - 默认为 `bottom`
+ - 控制开发工具面板的停靠位置
+- `client?: QueryClient`
+ - 传入自定义 QueryClient。若不设置,则使用最近上下文中的实例
+- `errorTypes?: { name: string; initializer: (query: Query) => TError}`
+ - 用于预定义可触发的查询错误类型。当从 UI 切换该错误时,初始化函数会接收具体查询并返回一个 Error 对象
+- `styleNonce?: string`
+ - 传递 nonce 给添加到 document head 的 style 标签,适用于使用内容安全策略 (CSP) nonce 允许内联样式的场景
+- `shadowDOMTarget?: ShadowRoot`
+ - 默认行为会将开发工具样式应用到 DOM 的 head 标签
+ - 传入 shadow DOM 目标节点可使样式作用于 shadow DOM 内部,而非 light DOM 的 head 标签
diff --git a/docs/zh-hans/framework/solid/guides/advanced-ssr.md b/docs/zh-hans/framework/solid/guides/advanced-ssr.md
new file mode 100644
index 00000000000..6990aba2e46
--- /dev/null
+++ b/docs/zh-hans/framework/solid/guides/advanced-ssr.md
@@ -0,0 +1,8 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:19:20.669Z'
+id: advanced-ssr
+title: 高级 SSR
+---
+
+待更新
diff --git a/docs/zh-hans/framework/solid/guides/background-fetching-indicators.md b/docs/zh-hans/framework/solid/guides/background-fetching-indicators.md
new file mode 100644
index 00000000000..ad3bfa3372b
--- /dev/null
+++ b/docs/zh-hans/framework/solid/guides/background-fetching-indicators.md
@@ -0,0 +1,9 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-03T22:43:30.028Z'
+id: background-fetching-indicators
+title: Background Fetching Indicators
+ref: docs/zh-hans/framework/react/guides/background-fetching-indicators.md
+replace:
+ 'useMutation[(]': 'useMutation(() => '
+---
diff --git a/docs/zh-hans/framework/solid/guides/caching.md b/docs/zh-hans/framework/solid/guides/caching.md
new file mode 100644
index 00000000000..eb5a68f1873
--- /dev/null
+++ b/docs/zh-hans/framework/solid/guides/caching.md
@@ -0,0 +1,7 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:51.601Z'
+id: caching
+title: Caching Examples
+ref: docs/zh-hans/framework/react/guides/caching.md
+---
diff --git a/docs/zh-hans/framework/solid/guides/default-query-function.md b/docs/zh-hans/framework/solid/guides/default-query-function.md
new file mode 100644
index 00000000000..3a2d13ec51c
--- /dev/null
+++ b/docs/zh-hans/framework/solid/guides/default-query-function.md
@@ -0,0 +1,14 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:51.564Z'
+id: default-query-function
+title: Default Query Function
+ref: docs/zh-hans/framework/react/guides/default-query-function.md
+replace:
+ '@tanstack/react-query': '@tanstack/solid-query'
+ 'useMutationState[(]': 'useMutationState(() => '
+ 'useMutation[(]': 'useMutation(() => '
+ 'useQuery[(]': 'useQuery(() => '
+ 'useQueries[(]': 'useQueries(() => '
+ 'useInfiniteQuery[(]': 'useInfiniteQuery(() => '
+---
diff --git a/docs/zh-hans/framework/solid/guides/dependent-queries.md b/docs/zh-hans/framework/solid/guides/dependent-queries.md
new file mode 100644
index 00000000000..5989569e8d3
--- /dev/null
+++ b/docs/zh-hans/framework/solid/guides/dependent-queries.md
@@ -0,0 +1,14 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:51.533Z'
+id: dependent-queries
+title: Dependent Queries
+ref: docs/zh-hans/framework/react/guides/dependent-queries.md
+replace:
+ '@tanstack/react-query': '@tanstack/solid-query'
+ 'useMutationState[(]': 'useMutationState(() => '
+ 'useMutation[(]': 'useMutation(() => '
+ 'useQuery[(]': 'useQuery(() => '
+ 'useQueries[(]': 'useQueries(() => '
+ 'useInfiniteQuery[(]': 'useInfiniteQuery(() => '
+---
diff --git a/docs/zh-hans/framework/solid/guides/disabling-queries.md b/docs/zh-hans/framework/solid/guides/disabling-queries.md
new file mode 100644
index 00000000000..a3fe15fce3d
--- /dev/null
+++ b/docs/zh-hans/framework/solid/guides/disabling-queries.md
@@ -0,0 +1,14 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:51.457Z'
+id: disabling-queries
+title: Disabling/Pausing Queries
+ref: docs/zh-hans/framework/react/guides/disabling-queries.md
+replace:
+ '@tanstack/react-query': '@tanstack/solid-query'
+ 'useMutationState[(]': 'useMutationState(() => '
+ 'useMutation[(]': 'useMutation(() => '
+ 'useQuery[(]': 'useQuery(() => '
+ 'useQueries[(]': 'useQueries(() => '
+ 'useInfiniteQuery[(]': 'useInfiniteQuery(() => '
+---
diff --git a/docs/zh-hans/framework/solid/guides/does-this-replace-client-state.md b/docs/zh-hans/framework/solid/guides/does-this-replace-client-state.md
new file mode 100644
index 00000000000..b5a4418e1e3
--- /dev/null
+++ b/docs/zh-hans/framework/solid/guides/does-this-replace-client-state.md
@@ -0,0 +1,9 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:51.499Z'
+id: does-this-replace-client-state
+title: Does TanStack Query replace global state managers?
+ref: docs/zh-hans/framework/react/guides/does-this-replace-client-state.md
+replace:
+ hook: function
+---
diff --git a/docs/zh-hans/framework/solid/guides/filters.md b/docs/zh-hans/framework/solid/guides/filters.md
new file mode 100644
index 00000000000..9c3e4389b29
--- /dev/null
+++ b/docs/zh-hans/framework/solid/guides/filters.md
@@ -0,0 +1,7 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:51.413Z'
+id: filters
+title: Filters
+ref: docs/zh-hans/framework/react/guides/filters.md
+---
diff --git a/docs/zh-hans/framework/solid/guides/important-defaults.md b/docs/zh-hans/framework/solid/guides/important-defaults.md
new file mode 100644
index 00000000000..8d8cb0d05a6
--- /dev/null
+++ b/docs/zh-hans/framework/solid/guides/important-defaults.md
@@ -0,0 +1,7 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:51.380Z'
+id: important-defaults
+title: Important Defaults
+ref: docs/zh-hans/framework/react/guides/important-defaults.md
+---
diff --git a/docs/zh-hans/framework/solid/guides/infinite-queries.md b/docs/zh-hans/framework/solid/guides/infinite-queries.md
new file mode 100644
index 00000000000..b68aea188f3
--- /dev/null
+++ b/docs/zh-hans/framework/solid/guides/infinite-queries.md
@@ -0,0 +1,14 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:51.344Z'
+id: infinite-queries
+title: Infinite Queries
+ref: docs/zh-hans/framework/react/guides/infinite-queries.md
+replace:
+ '@tanstack/react-query': '@tanstack/solid-query'
+ 'useMutationState[(]': 'useMutationState(() => '
+ 'useMutation[(]': 'useMutation(() => '
+ 'useQuery[(]': 'useQuery(() => '
+ 'useQueries[(]': 'useQueries(() => '
+ 'useInfiniteQuery[(]': 'useInfiniteQuery(() => '
+---
diff --git a/docs/zh-hans/framework/solid/guides/initial-query-data.md b/docs/zh-hans/framework/solid/guides/initial-query-data.md
new file mode 100644
index 00000000000..ebd25ac44ff
--- /dev/null
+++ b/docs/zh-hans/framework/solid/guides/initial-query-data.md
@@ -0,0 +1,14 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:51.311Z'
+id: initial-query-data
+title: Initial Query Data
+ref: docs/zh-hans/framework/react/guides/initial-query-data.md
+replace:
+ '@tanstack/react-query': '@tanstack/solid-query'
+ 'useMutationState[(]': 'useMutationState(() => '
+ 'useMutation[(]': 'useMutation(() => '
+ 'useQuery[(]': 'useQuery(() => '
+ 'useQueries[(]': 'useQueries(() => '
+ 'useInfiniteQuery[(]': 'useInfiniteQuery(() => '
+---
diff --git a/docs/zh-hans/framework/solid/guides/invalidations-from-mutations.md b/docs/zh-hans/framework/solid/guides/invalidations-from-mutations.md
new file mode 100644
index 00000000000..7de335211d9
--- /dev/null
+++ b/docs/zh-hans/framework/solid/guides/invalidations-from-mutations.md
@@ -0,0 +1,15 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:51.271Z'
+id: invalidations-from-mutations
+title: Invalidations from Mutations
+ref: docs/zh-hans/framework/react/guides/invalidations-from-mutations.md
+replace:
+ React: Solid
+ '@tanstack/react-query': '@tanstack/solid-query'
+ 'useMutationState[(]': 'useMutationState(() => '
+ 'useMutation[(]': 'useMutation(() => '
+ 'useQuery[(]': 'useQuery(() => '
+ 'useQueries[(]': 'useQueries(() => '
+ 'useInfiniteQuery[(]': 'useInfiniteQuery(() => '
+---
diff --git a/docs/zh-hans/framework/solid/guides/mutations.md b/docs/zh-hans/framework/solid/guides/mutations.md
new file mode 100644
index 00000000000..3285243ea15
--- /dev/null
+++ b/docs/zh-hans/framework/solid/guides/mutations.md
@@ -0,0 +1,15 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:51.239Z'
+id: mutations
+title: Mutations
+ref: docs/zh-hans/framework/react/guides/mutations.md
+replace:
+ React: Solid
+ '@tanstack/react-query': '@tanstack/solid-query'
+ 'useMutationState[(]': 'useMutationState(() => '
+ 'useMutation[(]': 'useMutation(() => '
+ 'useQuery[(]': 'useQuery(() => '
+ 'useQueries[(]': 'useQueries(() => '
+ 'useInfiniteQuery[(]': 'useInfiniteQuery(() => '
+---
diff --git a/docs/zh-hans/framework/solid/guides/network-mode.md b/docs/zh-hans/framework/solid/guides/network-mode.md
new file mode 100644
index 00000000000..802d1e8ecad
--- /dev/null
+++ b/docs/zh-hans/framework/solid/guides/network-mode.md
@@ -0,0 +1,7 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:51.201Z'
+id: network-mode
+title: Network Mode
+ref: docs/zh-hans/framework/react/guides/network-mode.md
+---
diff --git a/docs/zh-hans/framework/solid/guides/optimistic-updates.md b/docs/zh-hans/framework/solid/guides/optimistic-updates.md
new file mode 100644
index 00000000000..2a7ddc0e276
--- /dev/null
+++ b/docs/zh-hans/framework/solid/guides/optimistic-updates.md
@@ -0,0 +1,15 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:51.168Z'
+id: optimistic-updates
+title: Optimistic Updates
+ref: docs/zh-hans/framework/react/guides/optimistic-updates.md
+replace:
+ React: Solid
+ '@tanstack/react-query': '@tanstack/solid-query'
+ 'useMutationState[(]': 'useMutationState(() => '
+ 'useMutation[(]': 'useMutation(() => '
+ 'useQuery[(]': 'useQuery(() => '
+ 'useQueries[(]': 'useQueries(() => '
+ 'useInfiniteQuery[(]': 'useInfiniteQuery(() => '
+---
diff --git a/docs/zh-hans/framework/solid/guides/paginated-queries.md b/docs/zh-hans/framework/solid/guides/paginated-queries.md
new file mode 100644
index 00000000000..0816f8e2da4
--- /dev/null
+++ b/docs/zh-hans/framework/solid/guides/paginated-queries.md
@@ -0,0 +1,14 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:51.119Z'
+id: paginated-queries
+title: Paginated / Lagged Queries
+ref: docs/zh-hans/framework/react/guides/paginated-queries.md
+replace:
+ '@tanstack/react-query': '@tanstack/solid-query'
+ 'useMutationState[(]': 'useMutationState(() => '
+ 'useMutation[(]': 'useMutation(() => '
+ 'useQuery[(]': 'useQuery(() => '
+ 'useQueries[(]': 'useQueries(() => '
+ 'useInfiniteQuery[(]': 'useInfiniteQuery(() => '
+---
diff --git a/docs/zh-hans/framework/solid/guides/parallel-queries.md b/docs/zh-hans/framework/solid/guides/parallel-queries.md
new file mode 100644
index 00000000000..15c97b253e3
--- /dev/null
+++ b/docs/zh-hans/framework/solid/guides/parallel-queries.md
@@ -0,0 +1,14 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:51.082Z'
+id: parallel-queries
+title: Parallel Queries
+ref: docs/zh-hans/framework/react/guides/parallel-queries.md
+replace:
+ '@tanstack/react-query': '@tanstack/solid-query'
+ 'useMutationState[(]': 'useMutationState(() => '
+ 'useMutation[(]': 'useMutation(() => '
+ 'useQuery[(]': 'useQuery(() => '
+ 'useQueries[(]': 'useQueries(() => '
+ 'useInfiniteQuery[(]': 'useInfiniteQuery(() => '
+---
diff --git a/docs/zh-hans/framework/solid/guides/placeholder-query-data.md b/docs/zh-hans/framework/solid/guides/placeholder-query-data.md
new file mode 100644
index 00000000000..1521d1ef710
--- /dev/null
+++ b/docs/zh-hans/framework/solid/guides/placeholder-query-data.md
@@ -0,0 +1,16 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:51.054Z'
+id: placeholder-query-data
+title: Placeholder Query Data
+ref: docs/zh-hans/framework/react/guides/placeholder-query-data.md
+replace:
+ React: Solid
+ '@tanstack/react-query': '@tanstack/solid-query'
+ 'useMutationState[(]': 'useMutationState(() => '
+ 'useMutation[(]': 'useMutation(() => '
+ 'useQuery[(]': 'useQuery(() => '
+ 'useQueries[(]': 'useQueries(() => '
+ 'useInfiniteQuery[(]': 'useInfiniteQuery(() => '
+ useMemo: createMemo
+---
diff --git a/docs/zh-hans/framework/solid/guides/prefetching.md b/docs/zh-hans/framework/solid/guides/prefetching.md
new file mode 100644
index 00000000000..1df1f8659f2
--- /dev/null
+++ b/docs/zh-hans/framework/solid/guides/prefetching.md
@@ -0,0 +1,16 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:51.012Z'
+id: prefetching
+title: Prefetching
+ref: docs/zh-hans/framework/react/guides/prefetching.md
+replace:
+ React.lazy: Solid.lazy
+ '@tanstack/react-query': '@tanstack/solid-query'
+ 'useMutationState[(]': 'useMutationState(() => '
+ 'useMutation[(]': 'useMutation(() => '
+ 'useQuery[(]': 'useQuery(() => '
+ 'useQueries[(]': 'useQueries(() => '
+ 'useInfiniteQuery[(]': 'useInfiniteQuery(() => '
+ /docs/framework/react/examples/basic-react-query-file-based: /docs/framework/solid/examples/basic-solid-query-file-based
+---
diff --git a/docs/zh-hans/framework/solid/guides/queries.md b/docs/zh-hans/framework/solid/guides/queries.md
new file mode 100644
index 00000000000..4adce26c05f
--- /dev/null
+++ b/docs/zh-hans/framework/solid/guides/queries.md
@@ -0,0 +1,13 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:50.975Z'
+id: queries
+title: Queries
+ref: docs/zh-hans/framework/react/guides/queries.md
+replace:
+ '@tanstack/react-query': '@tanstack/solid-query'
+ 'useMutationState[(]': 'useMutationState(() => '
+ 'useMutation[(]': 'useMutation(() => '
+ 'useQuery[(]': 'useQuery(() => '
+ 'useQueries[(]': 'useQueries(() => '
+---
diff --git a/docs/zh-hans/framework/solid/guides/query-cancellation.md b/docs/zh-hans/framework/solid/guides/query-cancellation.md
new file mode 100644
index 00000000000..99039aeef11
--- /dev/null
+++ b/docs/zh-hans/framework/solid/guides/query-cancellation.md
@@ -0,0 +1,34 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:50.901Z'
+id: query-cancellation
+title: Query Cancellation
+ref: docs/zh-hans/framework/react/guides/query-cancellation.md
+replace:
+ '@tanstack/react-query': '@tanstack/solid-query'
+ 'useMutationState[(]': 'useMutationState(() => '
+ 'useMutation[(]': 'useMutation(() => '
+ 'useQuery[(]': 'useQuery(() => '
+ 'useQueries[(]': 'useQueries(() => '
+ 'useInfiniteQuery[(]': 'useInfiniteQuery(() => '
+---
+
+[//]: # 'Example7'
+
+```ts
+const query = useQuery({
+ queryKey: ['todos'],
+ queryFn: async ({ signal }) => {
+ const resp = await fetch('/todos', { signal })
+ return resp.json()
+ },
+})
+
+const queryClient = useQueryClient()
+
+function onButtonClick() {
+ queryClient.cancelQueries({ queryKey: ['todos'] })
+}
+```
+
+[//]: # 'Example7'
diff --git a/docs/zh-hans/framework/solid/guides/query-functions.md b/docs/zh-hans/framework/solid/guides/query-functions.md
new file mode 100644
index 00000000000..4e5d7641950
--- /dev/null
+++ b/docs/zh-hans/framework/solid/guides/query-functions.md
@@ -0,0 +1,14 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:50.871Z'
+id: query-functions
+title: Query Functions
+ref: docs/zh-hans/framework/react/guides/query-functions.md
+replace:
+ '@tanstack/react-query': '@tanstack/solid-query'
+ 'useMutationState[(]': 'useMutationState(() => '
+ 'useMutation[(]': 'useMutation(() => '
+ 'useQuery[(]': 'useQuery(() => '
+ 'useQueries[(]': 'useQueries(() => '
+ 'useInfiniteQuery[(]': 'useInfiniteQuery(() => '
+---
diff --git a/docs/zh-hans/framework/solid/guides/query-invalidation.md b/docs/zh-hans/framework/solid/guides/query-invalidation.md
new file mode 100644
index 00000000000..ee36b147cb3
--- /dev/null
+++ b/docs/zh-hans/framework/solid/guides/query-invalidation.md
@@ -0,0 +1,14 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:50.932Z'
+id: query-invalidation
+title: Query Invalidation
+ref: docs/zh-hans/framework/react/guides/query-invalidation.md
+replace:
+ '@tanstack/react-query': '@tanstack/solid-query'
+ 'useMutationState[(]': 'useMutationState(() => '
+ 'useMutation[(]': 'useMutation(() => '
+ 'useQuery[(]': 'useQuery(() => '
+ 'useQueries[(]': 'useQueries(() => '
+ 'useInfiniteQuery[(]': 'useInfiniteQuery(() => '
+---
diff --git a/docs/zh-hans/framework/solid/guides/query-keys.md b/docs/zh-hans/framework/solid/guides/query-keys.md
new file mode 100644
index 00000000000..772a399008a
--- /dev/null
+++ b/docs/zh-hans/framework/solid/guides/query-keys.md
@@ -0,0 +1,14 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:50.836Z'
+id: query-keys
+title: Query Keys
+ref: docs/zh-hans/framework/react/guides/query-keys.md
+replace:
+ '@tanstack/react-query': '@tanstack/solid-query'
+ 'useMutationState[(]': 'useMutationState(() => '
+ 'useMutation[(]': 'useMutation(() => '
+ 'useQuery[(]': 'useQuery(() => '
+ 'useQueries[(]': 'useQueries(() => '
+ 'useInfiniteQuery[(]': 'useInfiniteQuery(() => '
+---
diff --git a/docs/zh-hans/framework/solid/guides/query-options.md b/docs/zh-hans/framework/solid/guides/query-options.md
new file mode 100644
index 00000000000..8b498640514
--- /dev/null
+++ b/docs/zh-hans/framework/solid/guides/query-options.md
@@ -0,0 +1,14 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:50.787Z'
+id: query-options
+title: Query Options
+ref: docs/zh-hans/framework/react/guides/query-options.md
+replace:
+ '@tanstack/react-query': '@tanstack/solid-query'
+ 'useMutationState[(]': 'useMutationState(() => '
+ 'useMutation[(]': 'useMutation(() => '
+ 'useQuery[(]': 'useQuery(() => '
+ 'useQueries[(]': 'useQueries(() => '
+ 'useInfiniteQuery[(]': 'useInfiniteQuery(() => '
+---
diff --git a/docs/zh-hans/framework/solid/guides/query-retries.md b/docs/zh-hans/framework/solid/guides/query-retries.md
new file mode 100644
index 00000000000..be873582e26
--- /dev/null
+++ b/docs/zh-hans/framework/solid/guides/query-retries.md
@@ -0,0 +1,14 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:50.724Z'
+id: query-retries
+title: Query Retries
+ref: docs/zh-hans/framework/react/guides/query-retries.md
+replace:
+ '@tanstack/react-query': '@tanstack/solid-query'
+ 'useMutationState[(]': 'useMutationState(() => '
+ 'useMutation[(]': 'useMutation(() => '
+ 'useQuery[(]': 'useQuery(() => '
+ 'useQueries[(]': 'useQueries(() => '
+ 'useInfiniteQuery[(]': 'useInfiniteQuery(() => '
+---
diff --git a/docs/zh-hans/framework/solid/guides/request-waterfalls.md b/docs/zh-hans/framework/solid/guides/request-waterfalls.md
new file mode 100644
index 00000000000..7239c5821ec
--- /dev/null
+++ b/docs/zh-hans/framework/solid/guides/request-waterfalls.md
@@ -0,0 +1,15 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:50.755Z'
+id: request-waterfalls
+title: Request Waterfalls
+ref: docs/zh-hans/framework/react/guides/request-waterfalls.md
+replace:
+ React: Solid
+ '@tanstack/react-query': '@tanstack/solid-query'
+ 'useMutationState[(]': 'useMutationState(() => '
+ 'useMutation[(]': 'useMutation(() => '
+ 'useQuery[(]': 'useQuery(() => '
+ 'useQueries[(]': 'useQueries(() => '
+ 'useInfiniteQuery[(]': 'useInfiniteQuery(() => '
+---
diff --git a/docs/zh-hans/framework/solid/guides/scroll-restoration.md b/docs/zh-hans/framework/solid/guides/scroll-restoration.md
new file mode 100644
index 00000000000..9aabfc60ebc
--- /dev/null
+++ b/docs/zh-hans/framework/solid/guides/scroll-restoration.md
@@ -0,0 +1,7 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:50.683Z'
+id: scroll-restoration
+title: Scroll Restoration
+ref: docs/zh-hans/framework/react/guides/scroll-restoration.md
+---
diff --git a/docs/zh-hans/framework/solid/guides/ssr.md b/docs/zh-hans/framework/solid/guides/ssr.md
new file mode 100644
index 00000000000..b353aa0d8f9
--- /dev/null
+++ b/docs/zh-hans/framework/solid/guides/ssr.md
@@ -0,0 +1,8 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:17:13.047Z'
+id: ssr
+title: SSR
+---
+
+即将推出
diff --git a/docs/zh-hans/framework/solid/guides/suspense.md b/docs/zh-hans/framework/solid/guides/suspense.md
new file mode 100644
index 00000000000..25ff6393ec0
--- /dev/null
+++ b/docs/zh-hans/framework/solid/guides/suspense.md
@@ -0,0 +1,44 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:17:08.121Z'
+id: suspense
+title: Suspense
+---
+
+Solid Query 也能与 Solid 的 [Suspense](https://docs.solidjs.com/reference/components/suspense) API 配合使用。
+
+为此,你需要用 Vue 提供的 `Suspense` 组件包裹可挂起的组件:
+
+```tsx
+import { Suspense } from 'solid-js'
+; }>
+
+
+```
+
+你可以使用 `solid-query` 提供的异步 `suspense` 函数:
+
+```vue
+
+```
+
+## 渲染时获取 (Fetch-on-render) vs 随取随渲染 (Render-as-you-fetch)
+
+开箱即用的 Solid Query 在 `suspense` 模式下无需额外配置即可作为**渲染时获取 (Fetch-on-render)**方案出色工作。这意味着当你的组件尝试挂载时,它们会触发查询获取并挂起,但只有在你导入并挂载它们之后才会发生。如果你想更上一层楼,实现**随取随渲染 (Render-as-you-fetch)**模式,我们建议在路由回调和/或用户交互事件上实现[预取 (Prefetching)](../prefetching),以便在组件挂载前就开始加载查询,甚至可以在导入或挂载其父组件之前就开始。
diff --git a/docs/zh-hans/framework/solid/guides/testing.md b/docs/zh-hans/framework/solid/guides/testing.md
new file mode 100644
index 00000000000..e3444d5b156
--- /dev/null
+++ b/docs/zh-hans/framework/solid/guides/testing.md
@@ -0,0 +1,6 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:50.621Z'
+id: testing
+title: Testing
+---
diff --git a/docs/zh-hans/framework/solid/guides/updates-from-mutation-responses.md b/docs/zh-hans/framework/solid/guides/updates-from-mutation-responses.md
new file mode 100644
index 00000000000..2ba85fab417
--- /dev/null
+++ b/docs/zh-hans/framework/solid/guides/updates-from-mutation-responses.md
@@ -0,0 +1,15 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:50.653Z'
+id: updates-from-mutation-responses
+title: Updates from Mutation Responses
+ref: docs/zh-hans/framework/react/guides/updates-from-mutation-responses.md
+replace:
+ React: Solid
+ '@tanstack/react-query': '@tanstack/solid-query'
+ 'useMutationState[(]': 'useMutationState(() => '
+ 'useMutation[(]': 'useMutation(() => '
+ 'useQuery[(]': 'useQuery(() => '
+ 'useQueries[(]': 'useQueries(() => '
+ 'useInfiniteQuery[(]': 'useInfiniteQuery(() => '
+---
diff --git a/docs/zh-hans/framework/solid/guides/window-focus-refetching.md b/docs/zh-hans/framework/solid/guides/window-focus-refetching.md
new file mode 100644
index 00000000000..8742890664c
--- /dev/null
+++ b/docs/zh-hans/framework/solid/guides/window-focus-refetching.md
@@ -0,0 +1,14 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:50.593Z'
+id: window-focus-refetching
+title: Window Focus Refetching
+ref: docs/zh-hans/framework/react/guides/window-focus-refetching.md
+replace:
+ '@tanstack/react-query': '@tanstack/solid-query'
+ 'useMutationState[(]': 'useMutationState(() => '
+ 'useMutation[(]': 'useMutation(() => '
+ 'useQuery[(]': 'useQuery(() => '
+ 'useQueries[(]': 'useQueries(() => '
+ 'useInfiniteQuery[(]': 'useInfiniteQuery(() => '
+---
diff --git a/docs/zh-hans/framework/solid/installation.md b/docs/zh-hans/framework/solid/installation.md
new file mode 100644
index 00000000000..7e44246cb6a
--- /dev/null
+++ b/docs/zh-hans/framework/solid/installation.md
@@ -0,0 +1,61 @@
+---
+source-updated-at: '2024-08-19T08:36:40.000Z'
+translation-updated-at: '2025-05-06T05:16:47.879Z'
+id: installation
+title: 安装
+---
+
+# 安装
+
+你可以通过 [NPM](https://npmjs.com/) 安装 Solid Query,或者通过 [ESM.sh](https://esm.sh/) 使用传统的 `
+```
+
+### 环境要求
+
+Solid Query 针对现代浏览器进行了优化,兼容以下浏览器配置:
+
+```
+Chrome >= 91
+Firefox >= 90
+Edge >= 91
+Safari >= 15
+iOS >= 15
+Opera >= 77
+```
+
+> 根据你的运行环境,可能需要添加 polyfill。如果需要支持旧版浏览器,你需要自行从 `node_modules` 转译该库。
diff --git a/docs/zh-hans/framework/solid/overview.md b/docs/zh-hans/framework/solid/overview.md
new file mode 100644
index 00000000000..607fd603019
--- /dev/null
+++ b/docs/zh-hans/framework/solid/overview.md
@@ -0,0 +1,140 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:16:29.033Z'
+id: overview
+title: 概述
+---
+
+Solid Query 是 TanStack Query 的官方 SolidJS 适配器,它能让你在 Web 应用中轻松实现**数据获取、缓存、同步和更新服务端状态**。
+
+## 动机
+
+SolidJS 作为一个快速、响应式且声明式的用户界面构建库,正日益受到欢迎。它开箱即用地提供了许多功能。诸如 `createSignal`、`createStore` 等基础功能非常适合管理客户端状态。与其他 UI 库不同,SolidJS 对异步数据管理有着独到的见解。`createResource` API 是处理 SolidJS 应用中服务端状态的强大基础功能。`resource` 是一种特殊的信号 (signal),可在数据加载状态时触发 `Suspense` 边界。
+
+```tsx
+import { createResource, ErrorBoundary, Suspense } from 'solid-js'
+import { render } from 'solid-js/web'
+
+function App() {
+ const [repository] = createResource(async () => {
+ const result = await fetch('https://api.github.com/repos/TanStack/query')
+ if (!result.ok) throw new Error('Failed to fetch data')
+ return result.json()
+ })
+
+ return (
+
+
Static Content
+ {/* An error while fetching will be caught by the ErrorBoundary */}
+
Something went wrong! }>
+ {/* Suspense will trigger a loading state while the data is being fetched */}
+ Loading...}>
+ {repository()?.updated_at}
+
+
+
+ )
+}
+
+const root = document.getElementById('root')
+
+render(() => , root!)
+```
+
+这非常棒!只需几行代码,你就能从 API 获取数据并处理加载和错误状态。但随着应用复杂度的增长,你将需要更多功能来有效管理服务端状态。这是因为**服务端状态与客户端状态完全不同**。首先,服务端状态:
+
+- 持久化存储在你无法控制或拥有的远程位置
+- 需要通过异步 API 进行获取和更新
+- 意味着共享所有权,可能被他人更改而无需你知晓
+- 如果不加注意,可能会在你的应用中变得“过时”
+
+一旦理解了应用中服务端状态的本质,**更多挑战将接踵而至**,例如:
+
+- 缓存...(可能是编程中最难实现的部分)
+- 将针对相同数据的多个请求去重为单个请求
+- 在后台更新“过时”数据
+- 判断数据何时“过时”
+- 尽可能快地反映数据更新
+- 分页和懒加载数据等性能优化
+- 管理服务端状态的内存和垃圾回收
+- 通过结构共享 (structural sharing) 记忆化查询结果
+
+此时 **Solid Query** 应运而生。该库封装了 `createResource`,并提供了一系列钩子和工具来有效管理服务端状态。它**开箱即用、零配置**,并可根据应用增长按需定制。
+
+从技术角度来看,Solid Query 能:
+
+- 帮助你移除应用中**大量**复杂且难以理解的代码,仅用少量 Solid Query 逻辑替代
+- 提升应用可维护性,轻松构建新功能而无需担心接入新的服务端状态数据源
+- 通过使应用感觉更快、响应更迅速,直接影响终端用户体验
+- 可能帮助你节省带宽并提升内存性能
+
+## 说够了,直接看代码吧!
+
+在下面的示例中,你可以看到 Solid Query 最基本、简单的用法,用于获取 TanStack Query GitHub 项目的统计信息:
+
+```tsx
+import { ErrorBoundary, Suspense } from 'solid-js'
+import {
+ useQuery,
+ QueryClient,
+ QueryClientProvider,
+} from '@tanstack/solid-query'
+
+function App() {
+ const repositoryQuery = useQuery(() => ({
+ queryKey: ['TanStack Query'],
+ queryFn: async () => {
+ const result = await fetch('https://api.github.com/repos/TanStack/query')
+ if (!result.ok) throw new Error('Failed to fetch data')
+ return result.json()
+ },
+ staleTime: 1000 * 60 * 5, // 5 minutes
+ throwOnError: true, // Throw an error if the query fails
+ }))
+
+ return (
+
+
Static Content
+ {/* An error while fetching will be caught by the ErrorBoundary */}
+
Something went wrong! }>
+ {/* Suspense will trigger a loading state while the data is being fetched */}
+ Loading...}>
+ {/*
+ The `data` property on a query is a SolidJS resource
+ so it will work with Suspense and transitions out of the box!
+ */}
+ {repositoryQuery.data?.updated_at}
+
+
+
+ )
+}
+
+const root = document.getElementById('root')
+const client = new QueryClient()
+
+render(
+ () => (
+
+
+
+ ),
+ root!,
+)
+```
+
+## 看起来代码量反而更多了?
+
+确实如此!但正是这几行代码开启了一个全新的可能性世界。在上面的示例中,你的查询会被缓存 5 分钟,这意味着如果应用中任何地方在 5 分钟内挂载了使用相同查询的新组件,它将不会重新获取数据,而是使用缓存数据。这只是 Solid Query 开箱即用提供的众多功能之一。其他功能包括:
+
+- **自动重新获取**:当查询变得“过时”(根据 `staleTime` 选项判断)时,会自动在后台重新获取
+- **自动缓存**:查询默认被缓存并在整个应用中共享
+- **请求去重**:多个组件可以共享同一查询并只发起一次请求
+- **自动垃圾回收**:不再需要的查询会被自动垃圾回收
+- **窗口焦点重新获取**:当应用重新获得焦点时,查询会自动重新获取
+- **分页**:内置分页支持
+- **请求取消**:自动取消过时或不必要的请求
+- **轮询/实时更新**:通过简单的 `refetchInterval` 选项即可轻松实现轮询或实时更新
+- **服务端渲染 (SSR) 支持**:Solid Query 与服务端渲染完美配合
+- **乐观更新**:轻松通过乐观更新缓存
+- **更多功能...**
diff --git a/docs/zh-hans/framework/solid/plugins/broadcastQueryClient.md b/docs/zh-hans/framework/solid/plugins/broadcastQueryClient.md
new file mode 100644
index 00000000000..88dc004cadb
--- /dev/null
+++ b/docs/zh-hans/framework/solid/plugins/broadcastQueryClient.md
@@ -0,0 +1,9 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:50.562Z'
+id: broadcastQueryClient
+title: broadcastQueryClient (Experimental)
+ref: docs/zh-hans/framework/react/plugins/broadcastQueryClient.md
+replace:
+ react-query: vue-query
+---
diff --git a/docs/zh-hans/framework/solid/plugins/createPersister.md b/docs/zh-hans/framework/solid/plugins/createPersister.md
new file mode 100644
index 00000000000..ae6e68aac61
--- /dev/null
+++ b/docs/zh-hans/framework/solid/plugins/createPersister.md
@@ -0,0 +1,9 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:50.529Z'
+id: createPersister
+title: experimental_createPersister
+ref: docs/zh-hans/framework/react/plugins/createPersister.md
+replace:
+ react-query: solid-query
+---
diff --git a/docs/zh-hans/framework/solid/quick-start.md b/docs/zh-hans/framework/solid/quick-start.md
new file mode 100644
index 00000000000..a6cdb282e35
--- /dev/null
+++ b/docs/zh-hans/framework/solid/quick-start.md
@@ -0,0 +1,231 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-03T22:08:58.056Z'
+id: quick-start
+title: 快速开始
+---
+
+`@tanstack/solid-query` 包为在 SolidJS 中使用 TanStack Query 提供了一流的 API。
+
+## 示例
+
+```tsx
+import {
+ QueryClient,
+ QueryClientProvider,
+ useQuery,
+} from '@tanstack/solid-query'
+import { Switch, Match, For } from 'solid-js'
+
+const queryClient = new QueryClient()
+
+function Example() {
+ const query = useQuery(() => ({
+ queryKey: ['todos'],
+ queryFn: fetchTodos,
+ }))
+
+ return (
+
+
+
+ Loading...
+
+
+ Error: {query.error.message}
+
+
+ {(todo) => {todo.title}
}
+
+
+
+ )
+}
+
+function App() {
+ return (
+
+
+
+ )
+}
+```
+
+## 可用函数
+
+Solid Query 提供了一系列实用的基础功能和函数,可以更轻松地管理 SolidJS 应用中的服务端状态 (server state)。
+
+- `useQuery`
+- `createQueries`
+- `createInfiniteQueries`
+- `createMutation`
+- `useIsFetching`
+- `useIsMutating`
+- `useQueryClient`
+- `QueryClient`
+- `QueryClientProvider`
+
+## Solid Query 与 React Query 的重要区别
+
+Solid Query 提供的 API 与 React Query 类似,但需要注意一些关键差异。
+
+- 上述 `solid-query` 基础功能(如 `useQuery`、`createMutation`、`useIsFetching`)的参数是函数,以便在响应式作用域 (reactive scope) 中进行追踪。
+
+```tsx
+// ❌ React 版本
+useQuery({
+ queryKey: ['todos', todo],
+ queryFn: fetchTodos,
+})
+
+// ✅ Solid 版本
+useQuery(() => ({
+ queryKey: ['todos', todo],
+ queryFn: fetchTodos,
+}))
+```
+
+- 如果在 `` 边界内访问查询数据,Suspense 会默认生效。
+
+```tsx
+import { For, Suspense } from 'solid-js'
+
+function Example() {
+ const query = useQuery(() => ({
+ queryKey: ['todos'],
+ queryFn: fetchTodos,
+ }))
+ return (
+
+ {/* ✅ 会触发加载状态,数据在 Suspense 边界内访问。 */}
+
+ {(todo) => {todo.title}
}
+
+ {/* ❌ 不会触发加载状态,数据未在 Suspense 边界内访问。 */}
+
{(todo) => {todo.title}
}
+
+ )
+}
+```
+
+- Solid Query 的基础功能(`createX`)不支持解构。这些函数的返回值是一个存储 (store),其属性仅在响应式上下文中被追踪。
+
+```tsx
+import {
+ QueryClient,
+ QueryClientProvider,
+ useQuery,
+} from '@tanstack/solid-query'
+import { Match, Switch } from 'solid-js'
+
+const queryClient = new QueryClient()
+
+export default function App() {
+ return (
+
+
+
+ )
+}
+
+function Example() {
+ // ❌ React 版本 —— 支持在响应式上下文外解构
+ // const { isPending, error, data } = useQuery({
+ // queryKey: ['repoData'],
+ // queryFn: () =>
+ // fetch('https://api.github.com/repos/tannerlinsley/react-query').then(
+ // (res) => res.json()
+ // ),
+ // })
+
+ // ✅ Solid 版本 —— 不支持在响应式上下文外解构
+ const query = useQuery(() => ({
+ queryKey: ['repoData'],
+ queryFn: () =>
+ fetch('https://api.github.com/repos/tannerlinsley/react-query').then(
+ (res) => res.json(),
+ ),
+ }))
+
+ // ✅ 在 JSX 响应式上下文中访问查询属性
+ return (
+
+ Loading...
+ Error: {query.error.message}
+
+
+
{query.data.name}
+
{query.data.description}
+
👀 {query.data.subscribers_count} {' '}
+
✨ {query.data.stargazers_count} {' '}
+
🍴 {query.data.forks_count}
+
+
+
+ )
+}
+```
+
+- 可以直接将信号 (Signal) 和存储值 (store value) 传递给函数参数。Solid Query 会自动更新查询存储 (store)。
+
+```tsx
+import {
+ QueryClient,
+ QueryClientProvider,
+ useQuery,
+} from '@tanstack/solid-query'
+import { createSignal, For } from 'solid-js'
+
+const queryClient = new QueryClient()
+
+function Example() {
+ const [enabled, setEnabled] = createSignal(false)
+ const [todo, setTodo] = createSignal(0)
+
+ // ✅ 直接传递信号是安全的,当信号值变化时观察者会自动更新
+ const todosQuery = useQuery(() => ({
+ queryKey: ['todos'],
+ queryFn: fetchTodos,
+ enabled: enabled(),
+ }))
+
+ const todoDetailsQuery = useQuery(() => ({
+ queryKey: ['todo', todo()],
+ queryFn: fetchTodo,
+ enabled: todo() > 0,
+ }))
+
+ return (
+
+
+
+ Loading...
+
+
+ Error: {todosQuery.error.message}
+
+
+
+ {(todo) => (
+ setTodo(todo.id)}>{todo.title}
+ )}
+
+
+
+
setEnabled(!enabled())}>Toggle enabled
+
+ )
+}
+
+function App() {
+ return (
+
+
+
+ )
+}
+```
+
+- 可以使用 SolidJS 原生的 `ErrorBoundary` 组件捕获和重置错误。将 `throwOnError` 或 `suspense` 选项设置为 `true` 以确保错误被抛出到 `ErrorBoundary`。
+
+- 由于属性追踪是通过 Solid 的细粒度响应式系统处理的,因此不需要 `notifyOnChangeProps` 等选项。
diff --git a/docs/zh-hans/framework/solid/reference/hydration.md b/docs/zh-hans/framework/solid/reference/hydration.md
new file mode 100644
index 00000000000..3ebbcdb45e2
--- /dev/null
+++ b/docs/zh-hans/framework/solid/reference/hydration.md
@@ -0,0 +1,12 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:50.469Z'
+id: hydration
+title: hydration
+ref: docs/zh-hans/framework/react/reference/hydration.md
+replace:
+ '@tanstack/react-query': '@tanstack/solid-query'
+---
+
+[//]: # 'HydrationBoundary'
+[//]: # 'HydrationBoundary'
diff --git a/docs/zh-hans/framework/solid/reference/infiniteQueryOptions.md b/docs/zh-hans/framework/solid/reference/infiniteQueryOptions.md
new file mode 100644
index 00000000000..181706ad27a
--- /dev/null
+++ b/docs/zh-hans/framework/solid/reference/infiniteQueryOptions.md
@@ -0,0 +1,7 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:50.499Z'
+id: infiniteQueryOptions
+title: infiniteQueryOptions
+ref: docs/zh-hans/framework/react/reference/infiniteQueryOptions.md
+---
diff --git a/docs/zh-hans/framework/solid/reference/queryOptions.md b/docs/zh-hans/framework/solid/reference/queryOptions.md
new file mode 100644
index 00000000000..6456cc59024
--- /dev/null
+++ b/docs/zh-hans/framework/solid/reference/queryOptions.md
@@ -0,0 +1,7 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:50.436Z'
+id: queryOptions
+title: queryOptions
+ref: docs/zh-hans/framework/react/reference/queryOptions.md
+---
diff --git a/docs/zh-hans/framework/solid/reference/useInfiniteQuery.md b/docs/zh-hans/framework/solid/reference/useInfiniteQuery.md
new file mode 100644
index 00000000000..5126468eb2b
--- /dev/null
+++ b/docs/zh-hans/framework/solid/reference/useInfiniteQuery.md
@@ -0,0 +1,11 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:50.406Z'
+id: useInfiniteQuery
+title: useInfiniteQuery
+ref: docs/zh-hans/framework/react/reference/useInfiniteQuery.md
+replace:
+ '@tanstack/react-query': '@tanstack/solid-query'
+ 'useInfiniteQuery[(]': 'useInfiniteQuery(() => '
+ 'useMutation[(]': 'useMutation(() => '
+---
diff --git a/docs/zh-hans/framework/solid/reference/useIsFetching.md b/docs/zh-hans/framework/solid/reference/useIsFetching.md
new file mode 100644
index 00000000000..44d17fb0e2a
--- /dev/null
+++ b/docs/zh-hans/framework/solid/reference/useIsFetching.md
@@ -0,0 +1,9 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:50.261Z'
+id: useIsFetching
+title: useIsFetching
+ref: docs/zh-hans/framework/react/reference/useIsFetching.md
+replace:
+ '@tanstack/react-query': '@tanstack/solid-query'
+---
diff --git a/docs/zh-hans/framework/solid/reference/useIsMutating.md b/docs/zh-hans/framework/solid/reference/useIsMutating.md
new file mode 100644
index 00000000000..08e36d03823
--- /dev/null
+++ b/docs/zh-hans/framework/solid/reference/useIsMutating.md
@@ -0,0 +1,9 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:50.224Z'
+id: useIsMutating
+title: useIsMutating
+ref: docs/zh-hans/framework/react/reference/useIsMutating.md
+replace:
+ '@tanstack/react-query': '@tanstack/solid-query'
+---
diff --git a/docs/zh-hans/framework/solid/reference/useMutation.md b/docs/zh-hans/framework/solid/reference/useMutation.md
new file mode 100644
index 00000000000..16356fb4531
--- /dev/null
+++ b/docs/zh-hans/framework/solid/reference/useMutation.md
@@ -0,0 +1,11 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:50.299Z'
+id: useMutation
+title: useMutation
+ref: docs/zh-hans/framework/react/reference/useMutation.md
+replace:
+ '@tanstack/react-query': '@tanstack/solid-query'
+ 'useMutationState[(]': 'useMutationState(() => '
+ 'useMutation[(]': 'useMutation(() => '
+---
diff --git a/docs/zh-hans/framework/solid/reference/useMutationState.md b/docs/zh-hans/framework/solid/reference/useMutationState.md
new file mode 100644
index 00000000000..ec0530cc8bd
--- /dev/null
+++ b/docs/zh-hans/framework/solid/reference/useMutationState.md
@@ -0,0 +1,11 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:50.340Z'
+id: useMutationState
+title: useMutationState
+ref: docs/zh-hans/framework/react/reference/useMutationState.md
+replace:
+ '@tanstack/react-query': '@tanstack/solid-query'
+ 'useMutationState[(]': 'useMutationState(() => '
+ 'useMutation[(]': 'useMutation(() => '
+---
diff --git a/docs/zh-hans/framework/solid/reference/useQueries.md b/docs/zh-hans/framework/solid/reference/useQueries.md
new file mode 100644
index 00000000000..217f4af3b03
--- /dev/null
+++ b/docs/zh-hans/framework/solid/reference/useQueries.md
@@ -0,0 +1,10 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:50.154Z'
+id: useQueries
+title: useQueries
+ref: docs/zh-hans/framework/react/reference/useQueries.md
+replace:
+ '@tanstack/react-query': '@tanstack/solid-query'
+ 'useQueries[(]': 'useQueries(() => '
+---
diff --git a/docs/zh-hans/framework/solid/reference/useQuery.md b/docs/zh-hans/framework/solid/reference/useQuery.md
new file mode 100644
index 00000000000..71fd914aa02
--- /dev/null
+++ b/docs/zh-hans/framework/solid/reference/useQuery.md
@@ -0,0 +1,376 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:14:50.192Z'
+id: useQuery
+title: useQuery
+---
+
+```tsx
+const {
+ data,
+ dataUpdatedAt,
+ error,
+ errorUpdatedAt,
+ failureCount,
+ failureReason,
+ fetchStatus,
+ isError,
+ isFetched,
+ isFetchedAfterMount,
+ isFetching,
+ isInitialLoading,
+ isLoading,
+ isLoadingError,
+ isPaused,
+ isPending,
+ isPlaceholderData,
+ isRefetchError,
+ isRefetching,
+ isStale,
+ isSuccess,
+ refetch,
+ status,
+} = useQuery(
+ () => ({
+ queryKey,
+ queryFn,
+ enabled,
+ select,
+ placeholderData,
+ deferStream,
+ reconcile,
+ gcTime,
+ networkMode,
+ initialData,
+ initialDataUpdatedAt,
+ meta,
+ queryKeyHashFn,
+ refetchInterval,
+ refetchIntervalInBackground,
+ refetchOnMount,
+ refetchOnReconnect,
+ refetchOnWindowFocus,
+ retry,
+ retryOnMount,
+ retryDelay,
+ staleTime,
+ throwOnError,
+ }),
+ () => queryClient,
+)
+```
+
+## Usage example
+
+Here are some examples of how to use the `useQuery` primitive in Solid Query.
+
+### Basic
+
+The most basic usage of `useQuery` is to create a query that fetches data from an API.
+
+```tsx
+import { useQuery } from '@tanstack/solid-query'
+
+function App() {
+ const todos = useQuery(() => ({
+ queryKey: 'todos',
+ queryFn: async () => {
+ const response = await fetch('/api/todos')
+ if (!response.ok) {
+ throw new Error('Failed to fetch todos')
+ }
+ return response.json()
+ },
+ }))
+
+ return (
+
+
+ Error: {todos.error.message}
+
+
+ Loading...
+
+
+
+
Todos:
+
+ {(todo) => {todo.title} }
+
+
+
+
+ )
+}
+```
+
+### Reactive Options
+
+The reason why `useQuery` accepts a function that returns an object is to allow for reactive options. This is useful when query options depend on other values/signals that might change over time. Solid Query can track the passed function in a reactive scope and re-run it whenever the dependencies change.
+
+```tsx
+import { useQuery } from '@tanstack/solid-query'
+
+function App() {
+ const [filter, setFilter] = createSignal('all')
+
+ const todos = useQuery(() => ({
+ queryKey: ['todos', filter()],
+ queryFn: async () => {
+ const response = await fetch(`/api/todos?filter=${filter()}`)
+ if (!response.ok) {
+ throw new Error('Failed to fetch todos')
+ }
+ return response.json()
+ },
+ }))
+
+ return (
+
+
+ setFilter('all')}>All
+ setFilter('active')}>Active
+ setFilter('completed')}>Completed
+
+
+ Error: {todos.error.message}
+
+
+ Loading...
+
+
+
+
Todos:
+
+ {(todo) => {todo.title} }
+
+
+
+
+ )
+}
+```
+
+### Usage with `Suspense`
+
+`useQuery` supports triggering SolidJS `Suspense` and `ErrorBoundary` components when the query is in a pending or error state. This allows you to easily handle loading and error states in your components.
+
+```tsx
+import { useQuery } from '@tanstack/solid-query'
+
+function App() {
+ const todos = useQuery(() => ({
+ queryKey: 'todos',
+ queryFn: async () => {
+ const response = await fetch('/api/todos')
+ if (!response.ok) {
+ throw new Error('Failed to fetch todos')
+ }
+ return response.json()
+ },
+ throwOnError: true,
+ }))
+
+ return (
+ Error: {todos.error.message}}>
+ Loading...}>
+
+
Todos:
+
+ {(todo) => {todo.title} }
+
+
+
+
+ )
+}
+```
+
+## `useQuery` Parameters
+
+- ### Query Options - `Accessor`
+
+ - ##### `queryKey: unknown[]`
+ - **Required**
+ - The query key to use for this query.
+ - The query key will be hashed into a stable hash. See [Query Keys](../../guides/query-keys) for more information.
+ - The query will automatically update when this key changes (as long as `enabled` is not set to `false`).
+ - ##### `queryFn: (context: QueryFunctionContext) => Promise`
+ - **Required, but only if no default query function has been defined** See [Default Query Function](../../guides/default-query-function) for more information.
+ - The function that the query will use to request data.
+ - Receives a [QueryFunctionContext](../../guides/query-functions#queryfunctioncontext)
+ - Must return a promise that will either resolve data or throw an error. The data cannot be `undefined`.
+ - ##### `enabled: boolean`
+ - Set this to `false` to disable this query from automatically running.
+ - Can be used for [Dependent Queries](../../guides/dependent-queries).
+ - ##### `select: (data: TData) => unknown`
+ - Optional
+ - This option can be used to transform or select a part of the data returned by the query function. It affects the returned `data` value, but does not affect what gets stored in the query cache.
+ - The `select` function will only run if `data` changed, or if the reference to the `select` function itself changes. To optimize, wrap the function in `useCallback`.
+ - ##### `placeholderData: TData | (previousValue: TData | undefined; previousQuery: Query | undefined,) => TData`
+ - Optional
+ - If set, this value will be used as the placeholder data for this particular query observer while the query is still in the `pending` state.
+ - `placeholderData` is **not persisted** to the cache
+ - If you provide a function for `placeholderData`, as a first argument you will receive previously watched query data if available, and the second argument will be the complete previousQuery instance.
+ - ##### `deferStream: boolean`
+ - Optional
+ - Defaults to `false`
+ - Only applicable while rendering queries on the server with streaming.
+ - Set `deferStream` to `true` to wait for the query to resolve on the server before flushing the stream.
+ - This can be useful to avoid sending a loading state to the client before the query has resolved.
+ - ##### `reconcile: false | string | ((oldData: TData | undefined, newData: TData) => TData)`
+ - Optional
+ - Defaults to `false`
+ - Set this to a string to enable reconciliation between query results based on the string key.
+ - Set this to a function which accepts the old and new data and returns resolved data of the same type to implement custom reconciliation logic.
+ - ##### `gcTime: number | Infinity`
+ - Defaults to `5 * 60 * 1000` (5 minutes) or `Infinity` during SSR
+ - The time in milliseconds that unused/inactive cache data remains in memory. When a query's cache becomes unused or inactive, that cache data will be garbage collected after this duration. When different garbage collection times are specified, the longest one will be used.
+ - Note: the maximum allowed time is about 24 days. See [more](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#maximum_delay_value).
+ - If set to `Infinity`, will disable garbage collection
+ - ##### `networkMode: 'online' | 'always' | 'offlineFirst`
+ - optional
+ - defaults to `'online'`
+ - see [Network Mode](../../guides/network-mode) for more information.
+ - ##### `initialData: TData | () => TData`
+ - Optional
+ - If set, this value will be used as the initial data for the query cache (as long as the query hasn't been created or cached yet)
+ - If set to a function, the function will be called **once** during the shared/root query initialization, and be expected to synchronously return the initialData
+ - Initial data is considered stale by default unless a `staleTime` has been set.
+ - `initialData` **is persisted** to the cache
+ - ##### `initialDataUpdatedAt: number | (() => number | undefined)`
+ - Optional
+ - If set, this value will be used as the time (in milliseconds) of when the `initialData` itself was last updated.
+ - ##### `meta: Record`
+ - Optional
+ - If set, stores additional information on the query cache entry that can be used as needed. It will be accessible wherever the `query` is available, and is also part of the `QueryFunctionContext` provided to the `queryFn`.
+ - ##### `queryKeyHashFn: (queryKey: QueryKey) => string`
+ - Optional
+ - If specified, this function is used to hash the `queryKey` to a string.
+ - ##### `refetchInterval: number | false | ((query: Query) => number | false | undefined)`
+ - Optional
+ - If set to a number, all queries will continuously refetch at this frequency in milliseconds
+ - If set to a function, the function will be executed with the query to compute a frequency
+ - ##### `refetchIntervalInBackground: boolean`
+ - Optional
+ - If set to `true`, queries that are set to continuously refetch with a `refetchInterval` will continue to refetch while their tab/window is in the background
+ - ##### `refetchOnMount: boolean | "always" | ((query: Query) => boolean | "always")`
+ - Optional
+ - Defaults to `true`
+ - If set to `true`, the query will refetch on mount if the data is stale.
+ - If set to `false`, the query will not refetch on mount.
+ - If set to `"always"`, the query will always refetch on mount.
+ - If set to a function, the function will be executed with the query to compute the value
+ - ##### `refetchOnWindowFocus: boolean | "always" | ((query: Query) => boolean | "always")`
+ - Optional
+ - Defaults to `true`
+ - If set to `true`, the query will refetch on window focus if the data is stale.
+ - If set to `false`, the query will not refetch on window focus.
+ - If set to `"always"`, the query will always refetch on window focus.
+ - If set to a function, the function will be executed with the query to compute the value
+ - ##### `refetchOnReconnect: boolean | "always" | ((query: Query) => boolean | "always")`
+ - Optional
+ - Defaults to `true`
+ - If set to `true`, the query will refetch on reconnect if the data is stale.
+ - If set to `false`, the query will not refetch on reconnect.
+ - If set to `"always"`, the query will always refetch on reconnect.
+ - If set to a function, the function will be executed with the query to compute the value
+ - ##### `retry: boolean | number | (failureCount: number, error: TError) => boolean`
+ - If `false`, failed queries will not retry by default.
+ - If `true`, failed queries will retry infinitely.
+ - If set to a `number`, e.g. `3`, failed queries will retry until the failed query count meets that number.
+ - defaults to `3` on the client and `0` on the server
+ - ##### `retryOnMount: boolean`
+ - If set to `false`, the query will not be retried on mount if it contains an error. Defaults to `true`.
+ - ##### `retryDelay: number | (retryAttempt: number, error: TError) => number`
+ - This function receives a `retryAttempt` integer and the actual Error and returns the delay to apply before the next attempt in milliseconds.
+ - A function like `attempt => Math.min(attempt > 1 ? 2 ** attempt * 1000 : 1000, 30 * 1000)` applies exponential backoff.
+ - A function like `attempt => attempt * 1000` applies linear backoff.
+ - ##### `staleTime: number | Infinity`
+ - Optional
+ - Defaults to `0`
+ - The time in milliseconds after data is considered stale. This value only applies to the hook it is defined on.
+ - If set to `Infinity`, the data will never be considered stale
+ - ##### `throwOnError: undefined | boolean | (error: TError, query: Query) => boolean`
+ - Set this to `true` if you want errors to be thrown in the render phase and propagate to the nearest error boundary
+ - Set this to `false` to disable `suspense`'s default behavior of throwing errors to the error boundary.
+ - If set to a function, it will be passed the error and the query, and it should return a boolean indicating whether to show the error in an error boundary (`true`) or return the error as state (`false`)
+
+- ### Query Client - `Accessor`
+ - Optional
+ - Use this to use a custom QueryClient. Otherwise, the one from the nearest context will be used.
+
+## `useQuery` Return Value - `Store>`
+
+`useQuery` returns a SolidJS store with the following properties:
+
+- ##### `status: QueryStatus`
+ - Will be:
+ - `pending` if there's no cached data and no query attempt was finished yet.
+ - `error` if the query attempt resulted in an error. The corresponding `error` property has the error received from the attempted fetch
+ - `success` if the query has received a response with no errors and is ready to display its data. The corresponding `data` property on the query is the data received from the successful fetch or if the query's `enabled` property is set to `false` and has not been fetched yet `data` is the first `initialData` supplied to the query on initialization.
+- ##### `isPending: boolean`
+ - A derived boolean from the `status` variable above, provided for convenience.
+- ##### `isSuccess: boolean`
+ - A derived boolean from the `status` variable above, provided for convenience.
+- ##### `isError: boolean`
+ - A derived boolean from the `status` variable above, provided for convenience.
+- ##### `isLoadingError: boolean`
+ - Will be `true` if the query failed while fetching for the first time.
+- ##### `isRefetchError: boolean`
+ - Will be `true` if the query failed while refetching.
+- ##### `data: Resource`
+ - Defaults to `undefined`.
+ - The last successfully resolved data for the query.
+ - **Important**: The `data` property is a SolidJS resource. This means that if the data is accessed underneath a `` component,
+ it will trigger the Suspense boundary if the data is not available yet.
+- ##### `dataUpdatedAt: number`
+ - The timestamp for when the query most recently returned the `status` as `"success"`.
+- ##### `error: null | TError`
+ - Defaults to `null`
+ - The error object for the query, if an error was thrown.
+- ##### `errorUpdatedAt: number`
+ - The timestamp for when the query most recently returned the `status` as `"error"`.
+- ##### `isStale: boolean`
+ - Will be `true` if the data in the cache is invalidated or if the data is older than the given `staleTime`.
+- ##### `isPlaceholderData: boolean`
+ - Will be `true` if the data shown is the placeholder data.
+- ##### `isFetched: boolean`
+ - Will be `true` if the query has been fetched.
+- ##### `isFetchedAfterMount: boolean`
+ - Will be `true` if the query has been fetched after the component mounted.
+ - This property can be used to not show any previously cached data.
+- ##### `fetchStatus: FetchStatus`
+ - `fetching`: Is `true` whenever the queryFn is executing, which includes initial `pending` as well as background refetches.
+ - `paused`: The query wanted to fetch, but has been `paused`.
+ - `idle`: The query is not fetching.
+ - see [Network Mode](../../guides/network-mode) for more information.
+- ##### `isFetching: boolean`
+ - A derived boolean from the `fetchStatus` variable above, provided for convenience.
+- ##### `isPaused: boolean`
+ - A derived boolean from the `fetchStatus` variable above, provided for convenience.
+- ##### `isRefetching: boolean`
+ - Is `true` whenever a background refetch is in-flight, which _does not_ include initial `pending`
+ - Is the same as `isFetching && !isPending`
+- ##### `isLoading: boolean`
+ - Is `true` whenever the first fetch for a query is in-flight
+ - Is the same as `isFetching && isPending`
+- ##### `isInitialLoading: boolean`
+ - **deprecated**
+ - An alias for `isLoading`, will be removed in the next major version.
+- ##### `failureCount: number`
+ - The failure count for the query.
+ - Incremented every time the query fails.
+ - Reset to `0` when the query succeeds.
+- ##### `failureReason: null | TError`
+ - The failure reason for the query retry.
+ - Reset to `null` when the query succeeds.
+- ##### `errorUpdateCount: number`
+ - The sum of all errors.
+- ##### `refetch: (options: { throwOnError: boolean, cancelRefetch: boolean }) => Promise`
+ - A function to manually refetch the query.
+ - If the query errors, the error will only be logged. If you want an error to be thrown, pass the `throwOnError: true` option
+ - `cancelRefetch?: boolean`
+ - Defaults to `true`
+ - Per default, a currently running request will be cancelled before a new request is made
+ - When set to `false`, no refetch will be made if there is already a request running.
diff --git a/docs/zh-hans/framework/solid/typescript.md b/docs/zh-hans/framework/solid/typescript.md
new file mode 100644
index 00000000000..f5eb63eeed4
--- /dev/null
+++ b/docs/zh-hans/framework/solid/typescript.md
@@ -0,0 +1,219 @@
+---
+source-updated-at: '2025-04-03T21:54:40.000Z'
+translation-updated-at: '2025-05-06T05:19:16.449Z'
+id: typescript
+title: TypeScript
+---
+
+Solid Query 采用 **TypeScript** 编写,以确保库和您的项目具备类型安全!
+
+注意事项:
+
+- 当前类型系统要求使用 TypeScript **v4.7** 或更高版本
+- 本仓库中的类型变更被视为**非破坏性变更**,通常以 **patch** 版本号发布(否则每个类型增强都会导致主版本号变更!)
+- **强烈建议您将 solid-query 包版本锁定到特定 patch 版本,并在升级时预见到类型可能在任意版本间被修复或升级**
+- Solid Query 中与类型无关的公共 API 仍严格遵循语义化版本规范。
+
+## 类型推断
+
+Solid Query 中的类型通常能很好地流动,因此您无需自行添加类型注解
+
+```tsx
+import { useQuery } from '@tanstack/solid-query'
+
+const query = useQuery(() => ({
+ queryKey: ['number'],
+ queryFn: () => Promise.resolve(5),
+}))
+
+query.data
+// ^? (property) data: number | undefined
+```
+
+[typescript playground](https://www.typescriptlang.org/play/?#code/JYWwDg9gTgLgBAbzgYygUwIYzQRQK5pQCecAvnAGZQQhwDkAAjBgHYDOzyA1gPRsQAbYABMAtAEcCxOgFgAUPOQR28SYRIBeFOiy4pRABQGAlHA0A+OAYTy4duGuIBpNEQBccANp0WeEACNCOgBdABo4W3tHIgAxFg8TM0sABWoQYDY0ADp0fgEANzQDAFZjeVJjMoU5aKzhLAx5Hh57OAA9AH55brkgA)
+
+```tsx
+import { useQuery } from '@tanstack/solid-query'
+
+const query = useQuery(() => ({
+ queryKey: ['test'],
+ queryFn: () => Promise.resolve(5),
+ select: (data) => data.toString(),
+}))
+
+query.data
+// ^? (property) data: string | undefined
+```
+
+[typescript playground](https://www.typescriptlang.org/play/?#code/JYWwDg9gTgLgBAbzgYygUwIYzQRQK5pQCecAvnAGZQQhwDkAAjBgHYDOzyA1gPRsQAbYABMAtAEcCxOgFgAUPOQR28SYRIBeFOiy4pRABQGAlHA0A+OAYTy4duGuIBpNEQBccANp1sHOgF0AGjhbe0ciADEWDxMzSwAFahBgNjQAOnR+AQA3NAMAVmNA0LtUgTRkGBjhLAxTCzga5jSYCABlGChgFgBzE2K5UmNjeXlwtKaMeR4eezgAPQB+UYU5IA)
+
+当您的 `queryFn` 具有明确定义的返回类型时效果最佳。请注意大多数数据获取库默认返回 `any`,因此请确保将其提取到具有正确类型的函数中:
+
+```tsx
+const fetchGroups = (): Promise =>
+ axios.get('/groups').then((response) => response.data)
+
+const query = useQuery(() => ({
+ queryKey: ['groups'],
+ queryFn: fetchGroups,
+}))
+
+query.data
+// ^? (property) data: Group[] | undefined
+```
+
+[typescript playground](https://www.typescriptlang.org/play/?ssl=11&ssc=4&pln=6&pc=1#code/JYWwDg9gTgLgBAbzgYygUwIYzQRQK5pQCecAvnAGZQQhwDkAAjBgHYDOzyA1gPRsQAbYABMAtAEcCxOgFgAUKEiw4GAB7AIbStVp01GtrLnyYRMGjgBxanjBwAvIjgiAXHBZ4QAI0Jl585Ah2eAo0GGQAC2sIWy1HAAoASjcABR1gNjQAHmjbAG0AXQA+BxL9TQA6AHMw+LoeKpswQ0SKmAi0Fnj0Nkh2C3sSnr7MiuEsDET-OUDguElCEkdUTGx8Rfik0rh4hHk4A-mpIgBpNCI3PLpGmOa6AoAaOH3DheIAMRY3UPCoprYHvJSIkpsY5G8iGMJvIeDxDnAAHoAfmm8iAA)
+
+## 类型收窄
+
+Solid Query 使用[可辨识联合类型](https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes-func.html#discriminated-unions)作为查询结果,通过 `status` 字段和派生的状态布尔标志进行区分。这使您能够检查例如 `success` 状态来确保 `data` 已定义:
+
+```tsx
+const query = useQuery(() => ({
+ queryKey: ['number'],
+ queryFn: () => Promise.resolve(5),
+}))
+
+if (query.isSuccess) {
+ const data = query.data
+ // ^? const data: number
+}
+```
+
+[typescript playground](https://www.typescriptlang.org/play/?#code/JYWwDg9gTgLgBAbzgYygUwIYzQRQK5pQCecAvnAGZQQhwDkAAjBgHYDOzyA1gPRsQAbYABMAtAEcCxOgFgAUKEixEKdFjQBRChTTJ45KjXr8hYgFZtZc+cgjt4kwiQC8qzNnxOAFF4CUcZwA+OC8EeTg4R2IAaTQiAC44AG06FjwQACNCOgBdABpwyKkiADEWRL8A4IAFahBgNjQAOnQTADc0LwBWXwK5Ul9feXlgChCooiaGgGU8ZGQ0NjZ-MLkIiNt7OGEsDACipyad5kKInh51iIA9AH55UmHrOSA)
+
+## 错误字段类型标注
+
+错误类型默认为 `Error`,因为这符合大多数用户的预期。
+
+```tsx
+const query = useQuery(() => ({
+ queryKey: ['groups'],
+ queryFn: fetchGroups,
+}))
+
+query.error
+// ^? (property) error: Error | null
+```
+
+[typescript playground](https://www.typescriptlang.org/play/?#code/JYWwDg9gTgLgBAbzgYygUwIYzQRQK5pQCecAvnAGZQQhwDkAAjBgHYDOzyA1gPRsQAbYABMAtAEcCxOgFgAUKEiw4GAB7AIbStVp01GtrLnyYRMGjgBxanjBwAvIjgiAXHBZ4QAI0Jl585Ah2eAo0GGQAC2sIWy1HAAoASjcABR1gNjQAHmjbAG0AXQA+BxL9TQA6AHMw+LoeKpswQ0SKmAi0Fnj0Nkh2C3sSnr7MiuEsDET-OUDguElCEkdUTGx8Rfik0rh4hHk4A-mpIgBpNCI3PLpGmOa6AoAaOH3DheIAMRY3UPCoprYHvJSIkpsY5G8iBVCNQoPIeDxDnAAHoAfmm8iAA)
+
+如果您想抛出自定义错误,或根本不是 `Error` 的内容,可以指定错误字段的类型:
+
+```tsx
+const query = useQuery(() => ({
+ queryKey: ['groups'],
+ queryFn: fetchGroups,
+}))
+
+query.error
+// ^? (property) error: string | null
+```
+
+但这样做有个缺点:`useQuery` 所有其他泛型的类型推断将不再工作。通常认为抛出非 `Error` 的内容不是良好实践,因此如果您有像 `AxiosError` 这样的子类,可以使用*类型收窄*来使错误字段更具体:
+
+```tsx
+import axios from 'axios'
+
+const query = useQuery(() => ({
+ queryKey: ['groups'],
+ queryFn: fetchGroups,
+}))
+
+query.error
+// ^? (property) error: Error | null
+
+if (axios.isAxiosError(query.error)) {
+ query.error
+ // ^? (property) error: AxiosError
+}
+```
+
+[typescript playground](https://www.typescriptlang.org/play/?#code/JYWwDg9gTgLgBAbzgYygUwIYzQRQK5pQCecAvnAGZQQhwDkAAjBgHYDOzyA1gPRsQAbYABMAtAEcCxOgFgAUKEiw4GAB7AIbStVp01GtrLnyYRMGjgBxanjBwAvIjgiAXHBZ4QAI0Jl585Ah2eAo0GGQAC2sIWy1HAAoASjcABR1gNjQAHmjbAG0AXQA+BxL9TQA6AHMw+LoeKpswQ0SKmAi0Fnj0Nkh2C3sSnr7MiuEsDET-OUDguElCEkdUTGx8Rfik0rh4hHk4A-mpIgBpNCI3PLpGmOa6AoAaOH3DheIAMRY3UPCoprYHvJSIkpsY5G8iBVCNQoPIeDxDnAAHoAfmmwAoO3KbAqGQAgupNABRKAw+IQqGk6AgxAvA4U6HQOlweGI1FA+RAA)
+
+## 注册全局 `Error` 类型
+
+TanStack Query v5 提供了一种方式来设置全局错误类型,无需在调用处指定泛型,通过扩展 `Register` 接口实现。这将确保类型推断仍然有效,但错误字段将是指定的类型:
+
+```tsx
+import '@tanstack/solid-query'
+
+declare module '@tanstack/solid-query' {
+ interface Register {
+ defaultError: AxiosError
+ }
+}
+
+const query = useQuery(() => ({
+ queryKey: ['groups'],
+ queryFn: fetchGroups,
+}))
+
+query.error
+// ^? (property) error: AxiosError | null
+```
+
+## 注册全局 `Meta` 类型
+
+与注册[全局错误类型](#registering-a-global-error)类似,您也可以注册全局 `Meta` 类型。这确保[查询](../useQuery)和[变更](../createMutation)上的可选 `meta` 字段保持一致且类型安全。注意注册的类型必须扩展 `Record`,以便 `meta` 保持为对象。
+
+```ts
+import '@tanstack/solid-query'
+
+interface MyMeta extends Record {
+ // 您的 meta 类型定义
+}
+
+declare module '@tanstack/solid-query' {
+ interface Register {
+ queryMeta: MyMeta
+ mutationMeta: MyMeta
+ }
+}
+```
+
+## 查询选项类型标注
+
+如果将查询选项内联到 `useQuery` 中,您将获得自动类型推断。但您可能希望将查询选项提取到单独的函数中,以便在 `useQuery` 和例如 `prefetchQuery` 之间共享。这种情况下,您将失去类型推断。要恢复它,可以使用 `queryOptions` 辅助函数:
+
+```ts
+import { queryOptions } from '@tanstack/solid-query'
+
+function groupOptions() {
+ return queryOptions({
+ queryKey: ['groups'],
+ queryFn: fetchGroups,
+ staleTime: 5 * 1000,
+ })
+}
+
+useQuery(groupOptions)
+queryClient.prefetchQuery(groupOptions())
+```
+
+此外,`queryOptions` 返回的 `queryKey` 知道与之关联的 `queryFn`,我们可以利用这些类型信息使像 `queryClient.getQueryData` 这样的函数也能感知这些类型:
+
+```ts
+function groupOptions() {
+ return queryOptions({
+ queryKey: ['groups'],
+ queryFn: fetchGroups,
+ staleTime: 5 * 1000,
+ })
+}
+
+const data = queryClient.getQueryData(groupOptions().queryKey)
+// ^? const data: Group[] | undefined
+```
+
+如果没有 `queryOptions`,`data` 的类型将是 `unknown`,除非我们传递泛型:
+
+```ts
+const data = queryClient.getQueryData(['groups'])
+```
+
+## 使用 `skipToken` 类型安全地禁用查询
+
+如果使用 TypeScript,可以使用 `skipToken` 来禁用查询。这在您想基于条件禁用查询但仍希望保持查询类型安全时非常有用。
+
+更多信息请参阅[禁用查询](../disabling-queries)指南。
diff --git a/docs/zh-hans/framework/svelte/devtools.md b/docs/zh-hans/framework/svelte/devtools.md
new file mode 100644
index 00000000000..a4e275b72c5
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/devtools.md
@@ -0,0 +1,77 @@
+---
+source-updated-at: '2025-03-07T10:54:04.000Z'
+translation-updated-at: '2025-05-06T05:23:43.299Z'
+id: devtools
+title: 开发者工具
+---
+
+## 安装并导入开发者工具 (Devtools)
+
+开发者工具是一个独立的包,需要单独安装:
+
+```bash
+npm i @tanstack/svelte-query-devtools
+```
+
+或
+
+```bash
+pnpm add @tanstack/svelte-query-devtools
+```
+
+或
+
+```bash
+yarn add @tanstack/svelte-query-devtools
+```
+
+或
+
+```bash
+bun add @tanstack/svelte-query-devtools
+```
+
+可以通过以下方式导入开发者工具:
+
+```ts
+import { SvelteQueryDevtools } from '@tanstack/svelte-query-devtools'
+```
+
+## 浮动模式 (Floating Mode)
+
+浮动模式会将开发者工具作为一个固定的浮动元素挂载到你的应用中,并在屏幕角落提供一个切换按钮来显示或隐藏开发者工具。这个切换状态会被存储在 localStorage 中,并在页面刷新后保持记忆。
+
+将以下代码尽可能放在 Svelte 应用的顶层。越靠近页面根节点,效果越好!
+
+```ts
+
+
+
+ {/* 应用的其他部分 */}
+
+
+```
+
+### 配置选项
+
+- `initialIsOpen: Boolean`
+ - 设置为 `true` 可以让开发者工具默认处于打开状态
+- `buttonPosition?: "top-left" | "top-right" | "bottom-left" | "bottom-right" | "relative"`
+ - 默认为 `bottom-right`
+ - TanStack 徽标按钮的位置,用于打开和关闭开发者工具面板
+ - 如果设为 `relative`,按钮将渲染在你放置开发者工具的位置
+- `position?: "top" | "bottom" | "left" | "right"`
+ - 默认为 `bottom`
+ - Svelte Query 开发者工具面板的位置
+- `client?: QueryClient`,
+ - 用于指定自定义的 QueryClient。如果不设置,将使用最近上下文中的 QueryClient
+- `errorTypes?: { name: string; initializer: (query: Query) => TError}`
+ - 用于预定义一些可以在查询中触发的错误类型。当从 UI 切换该错误时,初始化器(带有特定查询)将被调用。它必须返回一个 Error 对象
+- `styleNonce?: string`
+ - 用于向添加到文档头部的 style 标签传递一个 nonce。这在需要使用内容安全策略 (CSP) nonce 来允许内联样式时很有用
+- `shadowDOMTarget?: ShadowRoot`
+ - 默认行为会将开发者工具的样式应用到 DOM 中的 head 标签
+ - 用于向开发者工具传递一个 shadow DOM 目标,这样样式将被应用到 shadow DOM 中,而不是 light DOM 的 head 标签里
diff --git a/docs/zh-hans/framework/svelte/installation.md b/docs/zh-hans/framework/svelte/installation.md
new file mode 100644
index 00000000000..2d2c71e3c3b
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/installation.md
@@ -0,0 +1,36 @@
+---
+source-updated-at: '2024-08-19T08:36:40.000Z'
+translation-updated-at: '2025-05-06T05:20:41.410Z'
+id: installation
+title: 安装
+---
+
+您可以通过 [NPM](https://npmjs.com) 安装 Svelte Query。
+
+> v5 版本目前作为发布候选版本提供。我们预计此后不会再有重大的 API 变更。我们鼓励您尝试使用并报告遇到的任何问题。
+
+### NPM
+
+```bash
+npm i @tanstack/svelte-query
+```
+
+或
+
+```bash
+pnpm add @tanstack/svelte-query
+```
+
+或
+
+```bash
+yarn add @tanstack/svelte-query
+```
+
+或
+
+```bash
+bun add @tanstack/svelte-query
+```
+
+> 想在下载前体验一下吗?试试这个 [基础示例](../examples/basic) 吧!
diff --git a/docs/zh-hans/framework/svelte/overview.md b/docs/zh-hans/framework/svelte/overview.md
new file mode 100644
index 00000000000..ce171fd74bd
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/overview.md
@@ -0,0 +1,76 @@
+---
+source-updated-at: '2025-01-23T16:50:04.000Z'
+translation-updated-at: '2025-05-06T05:21:37.348Z'
+id: overview
+title: 概述
+---
+
+`@tanstack/svelte-query` 包为通过 Svelte 使用 TanStack Query 提供了一流的 API。
+
+## 示例
+
+在项目根目录附近引入 QueryClientProvider:
+
+```svelte
+
+
+
+
+
+```
+
+然后在任意组件中调用函数(例如 createQuery):
+
+```svelte
+
+
+
+ {#if $query.isLoading}
+
Loading...
+ {:else if $query.isError}
+
Error: {$query.error.message}
+ {:else if $query.isSuccess}
+ {#each $query.data as todo}
+
{todo.title}
+ {/each}
+ {/if}
+
+```
+
+## SvelteKit
+
+如果使用 SvelteKit,请查看 [服务端渲染 (SSR) 与 SvelteKit](../ssr) 文档。
+
+## 可用函数
+
+Svelte Query 提供了以下实用函数和组件,可简化 Svelte 应用中的服务端状态管理:
+
+- `createQuery`
+- `createQueries`
+- `createInfiniteQuery`
+- `createMutation`
+- `useQueryClient`
+- `useIsFetching`
+- `useIsMutating`
+- `useHydrate`
+- ``
+- ``
+
+## Svelte Query 与 React Query 的重要区别
+
+Svelte Query 提供了与 React Query 相似的 API,但需注意以下关键差异:
+
+- Svelte Query 中的许多函数会返回 Svelte 的 store 对象。要响应式访问这些 store 的值,需要在变量名前添加 `$` 前缀。可通过 [Svelte store 文档](https://learn.svelte.dev/tutorial/writable-stores) 了解更多。
+- 若查询或变更依赖变量,必须使用 store 作为配置项。详见 [响应式文档](../reactivity)。
diff --git a/docs/zh-hans/framework/svelte/reactivity.md b/docs/zh-hans/framework/svelte/reactivity.md
new file mode 100644
index 00000000000..02c33becb74
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reactivity.md
@@ -0,0 +1,51 @@
+---
+source-updated-at: '2024-08-19T12:20:53.000Z'
+translation-updated-at: '2025-05-06T05:21:59.065Z'
+id: reactivity
+title: 响应式
+---
+
+Svelte 使用编译器构建代码以优化渲染。默认情况下,组件仅运行一次,除非在标记中被引用。若要对选项变化作出响应,您需要使用[存储 (store)](https://svelte.dev/docs/svelte-store)。
+
+在以下示例中,`refetchInterval` 选项从绑定到输入框的变量 `intervalMs` 设置。然而由于查询无法响应 `intervalMs` 的变化,当输入值改变时 `refetchInterval` 不会更新。
+
+```svelte
+
+
+
+```
+
+为解决此问题,我们可以将 `intervalMs` 转换为可写存储 (writable store)。查询选项随后可转换为派生存储 (derived store),以真正的响应式特性传入函数。
+
+```svelte
+
+
+
+```
diff --git a/docs/zh-hans/framework/svelte/reference/classes/hydrationboundary.md b/docs/zh-hans/framework/svelte/reference/classes/hydrationboundary.md
new file mode 100644
index 00000000000..1ba842230a4
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reference/classes/hydrationboundary.md
@@ -0,0 +1,276 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:20:30.717Z'
+id: HydrationBoundary
+title: HydrationBoundary
+---
+
+# Class: HydrationBoundary\
+
+Base class for Svelte components with some minor dev-enhancements. Used when dev=true.
+
+Can be used to create strongly typed Svelte components.
+
+#### Example:
+
+You have component library on npm called `component-library`, from which
+you export a component called `MyComponent`. For Svelte+TypeScript users,
+you want to provide typings. Therefore you create a `index.d.ts`:
+
+```ts
+import { SvelteComponent } from 'svelte'
+export class MyComponent extends SvelteComponent<{ foo: string }> {}
+```
+
+Typing this makes it possible for IDEs like VS Code with the Svelte extension
+to provide intellisense and to use the component like this in a Svelte file
+with TypeScript:
+
+```svelte
+
+
+
+```
+
+## Extends
+
+- `SvelteComponent_1`\<`Props`, `Events`\>
+
+## Type Parameters
+
+• **Props** _extends_ `Record`\<`string`, `any`\> = `any`
+
+• **Events** _extends_ `Record`\<`string`, `any`\> = `any`
+
+• **Slots** _extends_ `Record`\<`string`, `any`\> = `any`
+
+## Indexable
+
+\[`prop`: `string`\]: `any`
+
+## Constructors
+
+### new HydrationBoundary()
+
+```ts
+new HydrationBoundary(options): HydrationBoundary
+```
+
+#### Parameters
+
+• **options**: `ComponentConstructorOptions`\<`Props`\>
+
+#### Returns
+
+[`HydrationBoundary`](hydrationboundary.md)\<`Props`, `Events`, `Slots`\>
+
+#### Overrides
+
+`SvelteComponent_1.constructor`
+
+#### Defined in
+
+node_modules/.pnpm/svelte@4.2.18/node_modules/svelte/types/index.d.ts:144
+
+## Properties
+
+### $$
+
+```ts
+$$: any
+```
+
+### PRIVATE API
+
+Do not use, may change at any time
+
+#### Inherited from
+
+`SvelteComponent_1.$$`
+
+#### Defined in
+
+node_modules/.pnpm/svelte@4.2.18/node_modules/svelte/types/index.d.ts:102
+
+---
+
+### $$events_def
+
+```ts
+$$events_def: Events
+```
+
+For type checking capabilities only.
+Does not exist at runtime.
+
+### DO NOT USE!
+
+#### Defined in
+
+node_modules/.pnpm/svelte@4.2.18/node_modules/svelte/types/index.d.ts:158
+
+---
+
+### $$prop_def
+
+```ts
+$$prop_def: Props
+```
+
+For type checking capabilities only.
+Does not exist at runtime.
+
+### DO NOT USE!
+
+#### Defined in
+
+node_modules/.pnpm/svelte@4.2.18/node_modules/svelte/types/index.d.ts:151
+
+---
+
+### $$set
+
+```ts
+$$set: any
+```
+
+### PRIVATE API
+
+Do not use, may change at any time
+
+#### Inherited from
+
+`SvelteComponent_1.$$set`
+
+#### Defined in
+
+node_modules/.pnpm/svelte@4.2.18/node_modules/svelte/types/index.d.ts:109
+
+---
+
+### $$slot_def
+
+```ts
+$$slot_def: Slots
+```
+
+For type checking capabilities only.
+Does not exist at runtime.
+
+### DO NOT USE!
+
+#### Defined in
+
+node_modules/.pnpm/svelte@4.2.18/node_modules/svelte/types/index.d.ts:165
+
+## Methods
+
+### $capture_state()
+
+```ts
+$capture_state(): void
+```
+
+#### Returns
+
+`void`
+
+#### Defined in
+
+node_modules/.pnpm/svelte@4.2.18/node_modules/svelte/types/index.d.ts:167
+
+---
+
+### $destroy()
+
+```ts
+$destroy(): void
+```
+
+#### Returns
+
+`void`
+
+#### Inherited from
+
+`SvelteComponent_1.$destroy`
+
+#### Defined in
+
+node_modules/.pnpm/svelte@4.2.18/node_modules/svelte/types/index.d.ts:111
+
+---
+
+### $inject_state()
+
+```ts
+$inject_state(): void
+```
+
+#### Returns
+
+`void`
+
+#### Defined in
+
+node_modules/.pnpm/svelte@4.2.18/node_modules/svelte/types/index.d.ts:169
+
+---
+
+### $on()
+
+```ts
+$on(type, callback): () => void
+```
+
+#### Type Parameters
+
+• **K** _extends_ `string`
+
+#### Parameters
+
+• **type**: `K`
+
+• **callback**: `undefined` \| `null` \| (`e`) => `void`
+
+#### Returns
+
+`Function`
+
+##### Returns
+
+`void`
+
+#### Inherited from
+
+`SvelteComponent_1.$on`
+
+#### Defined in
+
+node_modules/.pnpm/svelte@4.2.18/node_modules/svelte/types/index.d.ts:113
+
+---
+
+### $set()
+
+```ts
+$set(props): void
+```
+
+#### Parameters
+
+• **props**: `Partial`\<`Props`\>
+
+#### Returns
+
+`void`
+
+#### Inherited from
+
+`SvelteComponent_1.$set`
+
+#### Defined in
+
+node_modules/.pnpm/svelte@4.2.18/node_modules/svelte/types/index.d.ts:115
diff --git a/docs/zh-hans/framework/svelte/reference/functions/createinfinitequery.md b/docs/zh-hans/framework/svelte/reference/functions/createinfinitequery.md
new file mode 100644
index 00000000000..1e667ff3e90
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reference/functions/createinfinitequery.md
@@ -0,0 +1,44 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:20:32.582Z'
+id: createInfiniteQuery
+title: createInfiniteQuery
+---
+
+# Function: createInfiniteQuery()
+
+```ts
+function createInfiniteQuery<
+ TQueryFnData,
+ TError,
+ TData,
+ TQueryKey,
+ TPageParam,
+>(options, queryClient?): CreateInfiniteQueryResult
+```
+
+## Type Parameters
+
+• **TQueryFnData**
+
+• **TError** = `Error`
+
+• **TData** = `InfiniteData`\<`TQueryFnData`, `unknown`\>
+
+• **TQueryKey** _extends_ `QueryKey` = `QueryKey`
+
+• **TPageParam** = `unknown`
+
+## Parameters
+
+• **options**: [`StoreOrVal`](../type-aliases/storeorval.md)\<[`CreateInfiniteQueryOptions`](../type-aliases/createinfinitequeryoptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryFnData`, `TQueryKey`, `TPageParam`\>\>
+
+• **queryClient?**: `QueryClient`
+
+## Returns
+
+[`CreateInfiniteQueryResult`](../type-aliases/createinfinitequeryresult.md)\<`TData`, `TError`\>
+
+## Defined in
+
+[packages/svelte-query/src/createInfiniteQuery.ts:16](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/svelte-query/src/createInfiniteQuery.ts#L16)
diff --git a/docs/zh-hans/framework/svelte/reference/functions/createmutation.md b/docs/zh-hans/framework/svelte/reference/functions/createmutation.md
new file mode 100644
index 00000000000..d01e7cbceee
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reference/functions/createmutation.md
@@ -0,0 +1,39 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:20:32.520Z'
+id: createMutation
+title: createMutation
+---
+
+# Function: createMutation()
+
+```ts
+function createMutation(
+ options,
+ queryClient?,
+): CreateMutationResult
+```
+
+## Type Parameters
+
+• **TData** = `unknown`
+
+• **TError** = `Error`
+
+• **TVariables** = `void`
+
+• **TContext** = `unknown`
+
+## Parameters
+
+• **options**: [`StoreOrVal`](../type-aliases/storeorval.md)\<[`CreateMutationOptions`](../type-aliases/createmutationoptions.md)\<`TData`, `TError`, `TVariables`, `TContext`\>\>
+
+• **queryClient?**: `QueryClient`
+
+## Returns
+
+[`CreateMutationResult`](../type-aliases/createmutationresult.md)\<`TData`, `TError`, `TVariables`, `TContext`\>
+
+## Defined in
+
+[packages/svelte-query/src/createMutation.ts:13](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/svelte-query/src/createMutation.ts#L13)
diff --git a/docs/zh-hans/framework/svelte/reference/functions/createqueries.md b/docs/zh-hans/framework/svelte/reference/functions/createqueries.md
new file mode 100644
index 00000000000..d3d8bf97c59
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reference/functions/createqueries.md
@@ -0,0 +1,39 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:20:32.402Z'
+id: createQueries
+title: createQueries
+---
+
+# Function: createQueries()
+
+```ts
+function createQueries(
+ __namedParameters,
+ queryClient?,
+): Readable
+```
+
+## Type Parameters
+
+• **T** _extends_ `any`[]
+
+• **TCombinedResult** = `T` _extends_ [] ? [] : `T` _extends_ [`Head`] ? [`GetCreateQueryResult`\<`Head`\>] : `T` _extends_ [`Head`, `...Tails[]`] ? [`...Tails[]`] _extends_ [] ? [] : [`...Tails[]`] _extends_ [`Head`] ? [`GetCreateQueryResult`\<`Head`\>, `GetCreateQueryResult`\<`Head`\>] : [`...Tails[]`] _extends_ [`Head`, `...Tails[]`] ? [`...Tails[]`] _extends_ [] ? [] : [`...Tails[]`] _extends_ [`Head`] ? [`GetCreateQueryResult`\<`Head`\>, `GetCreateQueryResult`\<`Head`\>, `GetCreateQueryResult`\<`Head`\>] : [`...Tails[]`] _extends_ [`Head`, `...Tails[]`] ? [`...(...)[]`] _extends_ [] ? [] : ... _extends_ ... ? ... : ... : [`...(...)[]`] _extends_ ...[] ? ...[] : ...[] : [`...Tails[]`] _extends_ `QueryObserverOptionsForCreateQueries`\<`TQueryFnData`, `TError`, `TData`, `any`\>[] ? `QueryObserverResult`\<`unknown` _extends_ `TData` ? `TQueryFnData` : `TData`, `unknown` _extends_ `TError` ? `Error` : `TError`\>[] : `QueryObserverResult`[] : `T` _extends_ `QueryObserverOptionsForCreateQueries`\<`TQueryFnData`, `TError`, `TData`, `any`\>[] ? `QueryObserverResult`\<`unknown` _extends_ `TData` ? `TQueryFnData` : `TData`, `unknown` _extends_ `TError` ? `Error` : `TError`\>[] : `QueryObserverResult`[]
+
+## Parameters
+
+• **\_\_namedParameters**
+
+• **\_\_namedParameters.combine?**
+
+• **\_\_namedParameters.queries?**: [`StoreOrVal`](../type-aliases/storeorval.md)\<[`...(T extends [] ? [] : T extends [Head] ? [GetQueryObserverOptionsForCreateQueries] : T extends [Head, ...Tails[]] ? [...Tails[]] extends [] ? [] : [...Tails[]] extends [Head] ? [GetQueryObserverOptionsForCreateQueries, GetQueryObserverOptionsForCreateQueries] : [...Tails[]] extends [Head, ...Tails[]] ? [...(...)[]] extends [] ? [] : (...) extends (...) ? (...) : (...) : readonly (...)[] extends [...(...)[]] ? [...(...)[]] : (...) extends (...) ? (...) : (...) : readonly unknown[] extends T ? T : T extends QueryObserverOptionsForCreateQueries[] ? QueryObserverOptionsForCreateQueries[] : QueryObserverOptionsForCreateQueries[])[]`]\>
+
+• **queryClient?**: `QueryClient`
+
+## Returns
+
+`Readable`\<`TCombinedResult`\>
+
+## Defined in
+
+[packages/svelte-query/src/createQueries.ts:205](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/svelte-query/src/createQueries.ts#L205)
diff --git a/docs/zh-hans/framework/svelte/reference/functions/createquery.md b/docs/zh-hans/framework/svelte/reference/functions/createquery.md
new file mode 100644
index 00000000000..fbfbdd95fc5
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reference/functions/createquery.md
@@ -0,0 +1,107 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:20:32.449Z'
+id: createQuery
+title: createQuery
+---
+
+# Function: createQuery()
+
+## createQuery(options, queryClient)
+
+```ts
+function createQuery(
+ options,
+ queryClient?,
+): DefinedCreateQueryResult
+```
+
+### Type Parameters
+
+• **TQueryFnData** = `unknown`
+
+• **TError** = `Error`
+
+• **TData** = `TQueryFnData`
+
+• **TQueryKey** _extends_ `QueryKey` = `QueryKey`
+
+### Parameters
+
+• **options**: [`StoreOrVal`](../type-aliases/storeorval.md)\<[`DefinedInitialDataOptions`](../type-aliases/definedinitialdataoptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`\>\>
+
+• **queryClient?**: `QueryClient`
+
+### Returns
+
+[`DefinedCreateQueryResult`](../type-aliases/definedcreatequeryresult.md)\<`TData`, `TError`\>
+
+### Defined in
+
+[packages/svelte-query/src/createQuery.ts:15](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/svelte-query/src/createQuery.ts#L15)
+
+## createQuery(options, queryClient)
+
+```ts
+function createQuery(
+ options,
+ queryClient?,
+): CreateQueryResult
+```
+
+### Type Parameters
+
+• **TQueryFnData** = `unknown`
+
+• **TError** = `Error`
+
+• **TData** = `TQueryFnData`
+
+• **TQueryKey** _extends_ `QueryKey` = `QueryKey`
+
+### Parameters
+
+• **options**: [`StoreOrVal`](../type-aliases/storeorval.md)\<[`UndefinedInitialDataOptions`](../type-aliases/undefinedinitialdataoptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`\>\>
+
+• **queryClient?**: `QueryClient`
+
+### Returns
+
+[`CreateQueryResult`](../type-aliases/createqueryresult.md)\<`TData`, `TError`\>
+
+### Defined in
+
+[packages/svelte-query/src/createQuery.ts:27](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/svelte-query/src/createQuery.ts#L27)
+
+## createQuery(options, queryClient)
+
+```ts
+function createQuery(
+ options,
+ queryClient?,
+): CreateQueryResult
+```
+
+### Type Parameters
+
+• **TQueryFnData** = `unknown`
+
+• **TError** = `Error`
+
+• **TData** = `TQueryFnData`
+
+• **TQueryKey** _extends_ `QueryKey` = `QueryKey`
+
+### Parameters
+
+• **options**: [`StoreOrVal`](../type-aliases/storeorval.md)\<[`CreateQueryOptions`](../type-aliases/createqueryoptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`\>\>
+
+• **queryClient?**: `QueryClient`
+
+### Returns
+
+[`CreateQueryResult`](../type-aliases/createqueryresult.md)\<`TData`, `TError`\>
+
+### Defined in
+
+[packages/svelte-query/src/createQuery.ts:39](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/svelte-query/src/createQuery.ts#L39)
diff --git a/docs/zh-hans/framework/svelte/reference/functions/getisrestoringcontext.md b/docs/zh-hans/framework/svelte/reference/functions/getisrestoringcontext.md
new file mode 100644
index 00000000000..17c933b29e0
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reference/functions/getisrestoringcontext.md
@@ -0,0 +1,22 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:20:32.365Z'
+id: getIsRestoringContext
+title: getIsRestoringContext
+---
+
+# Function: getIsRestoringContext()
+
+```ts
+function getIsRestoringContext(): Readable
+```
+
+Retrieves a `isRestoring` from Svelte's context
+
+## Returns
+
+`Readable`\<`boolean`\>
+
+## Defined in
+
+[packages/svelte-query/src/context.ts:28](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/svelte-query/src/context.ts#L28)
diff --git a/docs/zh-hans/framework/svelte/reference/functions/getqueryclientcontext.md b/docs/zh-hans/framework/svelte/reference/functions/getqueryclientcontext.md
new file mode 100644
index 00000000000..3aa1c881f34
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reference/functions/getqueryclientcontext.md
@@ -0,0 +1,22 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:20:32.325Z'
+id: getQueryClientContext
+title: getQueryClientContext
+---
+
+# Function: getQueryClientContext()
+
+```ts
+function getQueryClientContext(): QueryClient
+```
+
+Retrieves a Client from Svelte's context
+
+## Returns
+
+`QueryClient`
+
+## Defined in
+
+[packages/svelte-query/src/context.ts:9](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/svelte-query/src/context.ts#L9)
diff --git a/docs/zh-hans/framework/svelte/reference/functions/infinitequeryoptions.md b/docs/zh-hans/framework/svelte/reference/functions/infinitequeryoptions.md
new file mode 100644
index 00000000000..27df1d9d4e9
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reference/functions/infinitequeryoptions.md
@@ -0,0 +1,51 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:20:32.282Z'
+id: infiniteQueryOptions
+title: infiniteQueryOptions
+---
+
+# Function: infiniteQueryOptions()
+
+```ts
+function infiniteQueryOptions<
+ TQueryFnData,
+ TError,
+ TData,
+ TQueryKey,
+ TPageParam,
+>(
+ options,
+): CreateInfiniteQueryOptions<
+ TQueryFnData,
+ TError,
+ TData,
+ TQueryFnData,
+ TQueryKey,
+ TPageParam
+>
+```
+
+## Type Parameters
+
+• **TQueryFnData**
+
+• **TError** = `Error`
+
+• **TData** = `InfiniteData`\<`TQueryFnData`, `unknown`\>
+
+• **TQueryKey** _extends_ `QueryKey` = `QueryKey`
+
+• **TPageParam** = `unknown`
+
+## Parameters
+
+• **options**: [`CreateInfiniteQueryOptions`](../type-aliases/createinfinitequeryoptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryFnData`, `TQueryKey`, `TPageParam`\>
+
+## Returns
+
+[`CreateInfiniteQueryOptions`](../type-aliases/createinfinitequeryoptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryFnData`, `TQueryKey`, `TPageParam`\>
+
+## Defined in
+
+[packages/svelte-query/src/infiniteQueryOptions.ts:4](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/svelte-query/src/infiniteQueryOptions.ts#L4)
diff --git a/docs/zh-hans/framework/svelte/reference/functions/queryoptions.md b/docs/zh-hans/framework/svelte/reference/functions/queryoptions.md
new file mode 100644
index 00000000000..197d4dbbe89
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reference/functions/queryoptions.md
@@ -0,0 +1,68 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:20:32.242Z'
+id: queryOptions
+title: queryOptions
+---
+
+# Function: queryOptions()
+
+## queryOptions(options)
+
+```ts
+function queryOptions(
+ options,
+): DefinedInitialDataOptions & object
+```
+
+### Type Parameters
+
+• **TQueryFnData** = `unknown`
+
+• **TError** = `Error`
+
+• **TData** = `TQueryFnData`
+
+• **TQueryKey** _extends_ `QueryKey` = `QueryKey`
+
+### Parameters
+
+• **options**: [`DefinedInitialDataOptions`](../type-aliases/definedinitialdataoptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`\>
+
+### Returns
+
+[`DefinedInitialDataOptions`](../type-aliases/definedinitialdataoptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`\> & `object`
+
+### Defined in
+
+[packages/svelte-query/src/queryOptions.ts:26](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/svelte-query/src/queryOptions.ts#L26)
+
+## queryOptions(options)
+
+```ts
+function queryOptions(
+ options,
+): UndefinedInitialDataOptions & object
+```
+
+### Type Parameters
+
+• **TQueryFnData** = `unknown`
+
+• **TError** = `Error`
+
+• **TData** = `TQueryFnData`
+
+• **TQueryKey** _extends_ `QueryKey` = `QueryKey`
+
+### Parameters
+
+• **options**: [`UndefinedInitialDataOptions`](../type-aliases/undefinedinitialdataoptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`\>
+
+### Returns
+
+[`UndefinedInitialDataOptions`](../type-aliases/undefinedinitialdataoptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`\> & `object`
+
+### Defined in
+
+[packages/svelte-query/src/queryOptions.ts:37](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/svelte-query/src/queryOptions.ts#L37)
diff --git a/docs/zh-hans/framework/svelte/reference/functions/setisrestoringcontext.md b/docs/zh-hans/framework/svelte/reference/functions/setisrestoringcontext.md
new file mode 100644
index 00000000000..710f5128f8e
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reference/functions/setisrestoringcontext.md
@@ -0,0 +1,26 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:20:32.206Z'
+id: setIsRestoringContext
+title: setIsRestoringContext
+---
+
+# Function: setIsRestoringContext()
+
+```ts
+function setIsRestoringContext(isRestoring): void
+```
+
+Sets a `isRestoring` on Svelte's context
+
+## Parameters
+
+• **isRestoring**: `Readable`\<`boolean`\>
+
+## Returns
+
+`void`
+
+## Defined in
+
+[packages/svelte-query/src/context.ts:40](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/svelte-query/src/context.ts#L40)
diff --git a/docs/zh-hans/framework/svelte/reference/functions/setqueryclientcontext.md b/docs/zh-hans/framework/svelte/reference/functions/setqueryclientcontext.md
new file mode 100644
index 00000000000..dddf1dc47e7
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reference/functions/setqueryclientcontext.md
@@ -0,0 +1,26 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:20:32.163Z'
+id: setQueryClientContext
+title: setQueryClientContext
+---
+
+# Function: setQueryClientContext()
+
+```ts
+function setQueryClientContext(client): void
+```
+
+Sets a QueryClient on Svelte's context
+
+## Parameters
+
+• **client**: `QueryClient`
+
+## Returns
+
+`void`
+
+## Defined in
+
+[packages/svelte-query/src/context.ts:21](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/svelte-query/src/context.ts#L21)
diff --git a/docs/zh-hans/framework/svelte/reference/functions/usehydrate.md b/docs/zh-hans/framework/svelte/reference/functions/usehydrate.md
new file mode 100644
index 00000000000..967c02db23e
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reference/functions/usehydrate.md
@@ -0,0 +1,28 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:20:32.066Z'
+id: useHydrate
+title: useHydrate
+---
+
+# Function: useHydrate()
+
+```ts
+function useHydrate(state?, options?, queryClient?): void
+```
+
+## Parameters
+
+• **state?**: `unknown`
+
+• **options?**: `HydrateOptions`
+
+• **queryClient?**: `QueryClient`
+
+## Returns
+
+`void`
+
+## Defined in
+
+[packages/svelte-query/src/useHydrate.ts:8](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/svelte-query/src/useHydrate.ts#L8)
diff --git a/docs/zh-hans/framework/svelte/reference/functions/useisfetching.md b/docs/zh-hans/framework/svelte/reference/functions/useisfetching.md
new file mode 100644
index 00000000000..d496993af9e
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reference/functions/useisfetching.md
@@ -0,0 +1,26 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:20:32.113Z'
+id: useIsFetching
+title: useIsFetching
+---
+
+# Function: useIsFetching()
+
+```ts
+function useIsFetching(filters?, queryClient?): Readable
+```
+
+## Parameters
+
+• **filters?**: `QueryFilters`
+
+• **queryClient?**: `QueryClient`
+
+## Returns
+
+`Readable`\<`number`\>
+
+## Defined in
+
+[packages/svelte-query/src/useIsFetching.ts:10](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/svelte-query/src/useIsFetching.ts#L10)
diff --git a/docs/zh-hans/framework/svelte/reference/functions/useismutating.md b/docs/zh-hans/framework/svelte/reference/functions/useismutating.md
new file mode 100644
index 00000000000..147588a6ee8
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reference/functions/useismutating.md
@@ -0,0 +1,26 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:20:32.013Z'
+id: useIsMutating
+title: useIsMutating
+---
+
+# Function: useIsMutating()
+
+```ts
+function useIsMutating(filters?, queryClient?): Readable
+```
+
+## Parameters
+
+• **filters?**: `MutationFilters`
+
+• **queryClient?**: `QueryClient`
+
+## Returns
+
+`Readable`\<`number`\>
+
+## Defined in
+
+[packages/svelte-query/src/useIsMutating.ts:10](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/svelte-query/src/useIsMutating.ts#L10)
diff --git a/docs/zh-hans/framework/svelte/reference/functions/useisrestoring.md b/docs/zh-hans/framework/svelte/reference/functions/useisrestoring.md
new file mode 100644
index 00000000000..9c162214b4b
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reference/functions/useisrestoring.md
@@ -0,0 +1,20 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:20:31.953Z'
+id: useIsRestoring
+title: useIsRestoring
+---
+
+# Function: useIsRestoring()
+
+```ts
+function useIsRestoring(): Readable
+```
+
+## Returns
+
+`Readable`\<`boolean`\>
+
+## Defined in
+
+[packages/svelte-query/src/useIsRestoring.ts:4](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/svelte-query/src/useIsRestoring.ts#L4)
diff --git a/docs/zh-hans/framework/svelte/reference/functions/usemutationstate.md b/docs/zh-hans/framework/svelte/reference/functions/usemutationstate.md
new file mode 100644
index 00000000000..c92f2ad52fd
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reference/functions/usemutationstate.md
@@ -0,0 +1,30 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:20:31.828Z'
+id: useMutationState
+title: useMutationState
+---
+
+# Function: useMutationState()
+
+```ts
+function useMutationState(options, queryClient?): Readable
+```
+
+## Type Parameters
+
+• **TResult** = `MutationState`\<`unknown`, `Error`, `unknown`, `unknown`\>
+
+## Parameters
+
+• **options**: [`MutationStateOptions`](../type-aliases/mutationstateoptions.md)\<`TResult`\> = `{}`
+
+• **queryClient?**: `QueryClient`
+
+## Returns
+
+`Readable`\<`TResult`[]\>
+
+## Defined in
+
+[packages/svelte-query/src/useMutationState.ts:24](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/svelte-query/src/useMutationState.ts#L24)
diff --git a/docs/zh-hans/framework/svelte/reference/functions/usequeryclient.md b/docs/zh-hans/framework/svelte/reference/functions/usequeryclient.md
new file mode 100644
index 00000000000..5cfcd024dfd
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reference/functions/usequeryclient.md
@@ -0,0 +1,24 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:20:31.734Z'
+id: useQueryClient
+title: useQueryClient
+---
+
+# Function: useQueryClient()
+
+```ts
+function useQueryClient(queryClient?): QueryClient
+```
+
+## Parameters
+
+• **queryClient?**: `QueryClient`
+
+## Returns
+
+`QueryClient`
+
+## Defined in
+
+[packages/svelte-query/src/useQueryClient.ts:4](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/svelte-query/src/useQueryClient.ts#L4)
diff --git a/docs/zh-hans/framework/svelte/reference/index.md b/docs/zh-hans/framework/svelte/reference/index.md
new file mode 100644
index 00000000000..55ca8331a22
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reference/index.md
@@ -0,0 +1,59 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:20:30.679Z'
+id: '@tanstack/svelte-query'
+title: '@tanstack/svelte-query'
+---
+
+# @tanstack/svelte-query
+
+## References
+
+### QueryClientProvider
+
+Renames and re-exports [HydrationBoundary](classes/hydrationboundary.md)
+
+## Classes
+
+- [HydrationBoundary](classes/hydrationboundary.md)
+
+## Type Aliases
+
+- [CreateBaseMutationResult](type-aliases/createbasemutationresult.md)
+- [CreateBaseQueryOptions](type-aliases/createbasequeryoptions.md)
+- [CreateBaseQueryResult](type-aliases/createbasequeryresult.md)
+- [CreateInfiniteQueryOptions](type-aliases/createinfinitequeryoptions.md)
+- [CreateInfiniteQueryResult](type-aliases/createinfinitequeryresult.md)
+- [CreateMutateAsyncFunction](type-aliases/createmutateasyncfunction.md)
+- [CreateMutateFunction](type-aliases/createmutatefunction.md)
+- [CreateMutationOptions](type-aliases/createmutationoptions.md)
+- [CreateMutationResult](type-aliases/createmutationresult.md)
+- [CreateQueryOptions](type-aliases/createqueryoptions.md)
+- [CreateQueryResult](type-aliases/createqueryresult.md)
+- [DefinedCreateBaseQueryResult](type-aliases/definedcreatebasequeryresult.md)
+- [DefinedCreateQueryResult](type-aliases/definedcreatequeryresult.md)
+- [DefinedInitialDataOptions](type-aliases/definedinitialdataoptions.md)
+- [MutationStateOptions](type-aliases/mutationstateoptions.md)
+- [QueriesOptions](type-aliases/queriesoptions.md)
+- [QueriesResults](type-aliases/queriesresults.md)
+- [StoreOrVal](type-aliases/storeorval.md)
+- [UndefinedInitialDataOptions](type-aliases/undefinedinitialdataoptions.md)
+
+## Functions
+
+- [createInfiniteQuery](functions/createinfinitequery.md)
+- [createMutation](functions/createmutation.md)
+- [createQueries](functions/createqueries.md)
+- [createQuery](functions/createquery.md)
+- [getIsRestoringContext](functions/getisrestoringcontext.md)
+- [getQueryClientContext](functions/getqueryclientcontext.md)
+- [infiniteQueryOptions](functions/infinitequeryoptions.md)
+- [queryOptions](functions/queryoptions.md)
+- [setIsRestoringContext](functions/setisrestoringcontext.md)
+- [setQueryClientContext](functions/setqueryclientcontext.md)
+- [useHydrate](functions/usehydrate.md)
+- [useIsFetching](functions/useisfetching.md)
+- [useIsMutating](functions/useismutating.md)
+- [useIsRestoring](functions/useisrestoring.md)
+- [useMutationState](functions/usemutationstate.md)
+- [useQueryClient](functions/usequeryclient.md)
diff --git a/docs/zh-hans/framework/svelte/reference/type-aliases/createbasemutationresult.md b/docs/zh-hans/framework/svelte/reference/type-aliases/createbasemutationresult.md
new file mode 100644
index 00000000000..27d6430d240
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reference/type-aliases/createbasemutationresult.md
@@ -0,0 +1,34 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:20:31.682Z'
+id: CreateBaseMutationResult
+title: CreateBaseMutationResult
+---
+
+# Type Alias: CreateBaseMutationResult\
+
+```ts
+type CreateBaseMutationResult: Override, object> & object;
+```
+
+## Type declaration
+
+### mutateAsync
+
+```ts
+mutateAsync: CreateMutateAsyncFunction
+```
+
+## Type Parameters
+
+• **TData** = `unknown`
+
+• **TError** = `DefaultError`
+
+• **TVariables** = `unknown`
+
+• **TContext** = `unknown`
+
+## Defined in
+
+[packages/svelte-query/src/types.ts:113](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/svelte-query/src/types.ts#L113)
diff --git a/docs/zh-hans/framework/svelte/reference/type-aliases/createbasequeryoptions.md b/docs/zh-hans/framework/svelte/reference/type-aliases/createbasequeryoptions.md
new file mode 100644
index 00000000000..71c4e43e042
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reference/type-aliases/createbasequeryoptions.md
@@ -0,0 +1,30 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:20:31.606Z'
+id: CreateBaseQueryOptions
+title: CreateBaseQueryOptions
+---
+
+# Type Alias: CreateBaseQueryOptions\
+
+```ts
+type CreateBaseQueryOptions: QueryObserverOptions;
+```
+
+Options for createBaseQuery
+
+## Type Parameters
+
+• **TQueryFnData** = `unknown`
+
+• **TError** = `DefaultError`
+
+• **TData** = `TQueryFnData`
+
+• **TQueryData** = `TQueryFnData`
+
+• **TQueryKey** _extends_ `QueryKey` = `QueryKey`
+
+## Defined in
+
+[packages/svelte-query/src/types.ts:23](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/svelte-query/src/types.ts#L23)
diff --git a/docs/zh-hans/framework/svelte/reference/type-aliases/createbasequeryresult.md b/docs/zh-hans/framework/svelte/reference/type-aliases/createbasequeryresult.md
new file mode 100644
index 00000000000..e2fe97a6b0e
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reference/type-aliases/createbasequeryresult.md
@@ -0,0 +1,24 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:20:31.555Z'
+id: CreateBaseQueryResult
+title: CreateBaseQueryResult
+---
+
+# Type Alias: CreateBaseQueryResult\
+
+```ts
+type CreateBaseQueryResult: Readable>;
+```
+
+Result from createBaseQuery
+
+## Type Parameters
+
+• **TData** = `unknown`
+
+• **TError** = `DefaultError`
+
+## Defined in
+
+[packages/svelte-query/src/types.ts:32](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/svelte-query/src/types.ts#L32)
diff --git a/docs/zh-hans/framework/svelte/reference/type-aliases/createinfinitequeryoptions.md b/docs/zh-hans/framework/svelte/reference/type-aliases/createinfinitequeryoptions.md
new file mode 100644
index 00000000000..b38bbc055c2
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reference/type-aliases/createinfinitequeryoptions.md
@@ -0,0 +1,32 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:20:31.510Z'
+id: CreateInfiniteQueryOptions
+title: CreateInfiniteQueryOptions
+---
+
+# Type Alias: CreateInfiniteQueryOptions\
+
+```ts
+type CreateInfiniteQueryOptions: InfiniteQueryObserverOptions;
+```
+
+Options for createInfiniteQuery
+
+## Type Parameters
+
+• **TQueryFnData** = `unknown`
+
+• **TError** = `DefaultError`
+
+• **TData** = `TQueryFnData`
+
+• **TQueryData** = `TQueryFnData`
+
+• **TQueryKey** _extends_ `QueryKey` = `QueryKey`
+
+• **TPageParam** = `unknown`
+
+## Defined in
+
+[packages/svelte-query/src/types.ts:52](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/svelte-query/src/types.ts#L52)
diff --git a/docs/zh-hans/framework/svelte/reference/type-aliases/createinfinitequeryresult.md b/docs/zh-hans/framework/svelte/reference/type-aliases/createinfinitequeryresult.md
new file mode 100644
index 00000000000..db141eb4b45
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reference/type-aliases/createinfinitequeryresult.md
@@ -0,0 +1,24 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:20:31.468Z'
+id: CreateInfiniteQueryResult
+title: CreateInfiniteQueryResult
+---
+
+# Type Alias: CreateInfiniteQueryResult\
+
+```ts
+type CreateInfiniteQueryResult: Readable>;
+```
+
+Result from createInfiniteQuery
+
+## Type Parameters
+
+• **TData** = `unknown`
+
+• **TError** = `DefaultError`
+
+## Defined in
+
+[packages/svelte-query/src/types.ts:69](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/svelte-query/src/types.ts#L69)
diff --git a/docs/zh-hans/framework/svelte/reference/type-aliases/createmutateasyncfunction.md b/docs/zh-hans/framework/svelte/reference/type-aliases/createmutateasyncfunction.md
new file mode 100644
index 00000000000..b2bde559290
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reference/type-aliases/createmutateasyncfunction.md
@@ -0,0 +1,26 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:20:31.429Z'
+id: CreateMutateAsyncFunction
+title: CreateMutateAsyncFunction
+---
+
+# Type Alias: CreateMutateAsyncFunction\
+
+```ts
+type CreateMutateAsyncFunction: MutateFunction;
+```
+
+## Type Parameters
+
+• **TData** = `unknown`
+
+• **TError** = `DefaultError`
+
+• **TVariables** = `void`
+
+• **TContext** = `unknown`
+
+## Defined in
+
+[packages/svelte-query/src/types.ts:106](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/svelte-query/src/types.ts#L106)
diff --git a/docs/zh-hans/framework/svelte/reference/type-aliases/createmutatefunction.md b/docs/zh-hans/framework/svelte/reference/type-aliases/createmutatefunction.md
new file mode 100644
index 00000000000..478b2ff3782
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reference/type-aliases/createmutatefunction.md
@@ -0,0 +1,34 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:20:31.374Z'
+id: CreateMutateFunction
+title: CreateMutateFunction
+---
+
+# Type Alias: CreateMutateFunction()\
+
+```ts
+type CreateMutateFunction: (...args) => void;
+```
+
+## Type Parameters
+
+• **TData** = `unknown`
+
+• **TError** = `DefaultError`
+
+• **TVariables** = `void`
+
+• **TContext** = `unknown`
+
+## Parameters
+
+• ...**args**: `Parameters`\<`MutateFunction`\<`TData`, `TError`, `TVariables`, `TContext`\>\>
+
+## Returns
+
+`void`
+
+## Defined in
+
+[packages/svelte-query/src/types.ts:97](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/svelte-query/src/types.ts#L97)
diff --git a/docs/zh-hans/framework/svelte/reference/type-aliases/createmutationoptions.md b/docs/zh-hans/framework/svelte/reference/type-aliases/createmutationoptions.md
new file mode 100644
index 00000000000..203b9e57a13
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reference/type-aliases/createmutationoptions.md
@@ -0,0 +1,28 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:20:31.331Z'
+id: CreateMutationOptions
+title: CreateMutationOptions
+---
+
+# Type Alias: CreateMutationOptions\
+
+```ts
+type CreateMutationOptions: OmitKeyof, "_defaulted">;
+```
+
+Options for createMutation
+
+## Type Parameters
+
+• **TData** = `unknown`
+
+• **TError** = `DefaultError`
+
+• **TVariables** = `void`
+
+• **TContext** = `unknown`
+
+## Defined in
+
+[packages/svelte-query/src/types.ts:87](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/svelte-query/src/types.ts#L87)
diff --git a/docs/zh-hans/framework/svelte/reference/type-aliases/createmutationresult.md b/docs/zh-hans/framework/svelte/reference/type-aliases/createmutationresult.md
new file mode 100644
index 00000000000..ed67191651f
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reference/type-aliases/createmutationresult.md
@@ -0,0 +1,28 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:20:31.258Z'
+id: CreateMutationResult
+title: CreateMutationResult
+---
+
+# Type Alias: CreateMutationResult\
+
+```ts
+type CreateMutationResult: Readable>;
+```
+
+Result from createMutation
+
+## Type Parameters
+
+• **TData** = `unknown`
+
+• **TError** = `DefaultError`
+
+• **TVariables** = `unknown`
+
+• **TContext** = `unknown`
+
+## Defined in
+
+[packages/svelte-query/src/types.ts:126](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/svelte-query/src/types.ts#L126)
diff --git a/docs/zh-hans/framework/svelte/reference/type-aliases/createqueryoptions.md b/docs/zh-hans/framework/svelte/reference/type-aliases/createqueryoptions.md
new file mode 100644
index 00000000000..5e2d736b0ca
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reference/type-aliases/createqueryoptions.md
@@ -0,0 +1,28 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:20:31.208Z'
+id: CreateQueryOptions
+title: CreateQueryOptions
+---
+
+# Type Alias: CreateQueryOptions\
+
+```ts
+type CreateQueryOptions: CreateBaseQueryOptions;
+```
+
+Options for createQuery
+
+## Type Parameters
+
+• **TQueryFnData** = `unknown`
+
+• **TError** = `DefaultError`
+
+• **TData** = `TQueryFnData`
+
+• **TQueryKey** _extends_ `QueryKey` = `QueryKey`
+
+## Defined in
+
+[packages/svelte-query/src/types.ts:38](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/svelte-query/src/types.ts#L38)
diff --git a/docs/zh-hans/framework/svelte/reference/type-aliases/createqueryresult.md b/docs/zh-hans/framework/svelte/reference/type-aliases/createqueryresult.md
new file mode 100644
index 00000000000..6ceab1fdbd1
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reference/type-aliases/createqueryresult.md
@@ -0,0 +1,24 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:20:31.162Z'
+id: CreateQueryResult
+title: CreateQueryResult
+---
+
+# Type Alias: CreateQueryResult\
+
+```ts
+type CreateQueryResult: CreateBaseQueryResult;
+```
+
+Result from createQuery
+
+## Type Parameters
+
+• **TData** = `unknown`
+
+• **TError** = `DefaultError`
+
+## Defined in
+
+[packages/svelte-query/src/types.ts:46](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/svelte-query/src/types.ts#L46)
diff --git a/docs/zh-hans/framework/svelte/reference/type-aliases/definedcreatebasequeryresult.md b/docs/zh-hans/framework/svelte/reference/type-aliases/definedcreatebasequeryresult.md
new file mode 100644
index 00000000000..88f1a801d8c
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reference/type-aliases/definedcreatebasequeryresult.md
@@ -0,0 +1,24 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:20:31.069Z'
+id: DefinedCreateBaseQueryResult
+title: DefinedCreateBaseQueryResult
+---
+
+# Type Alias: DefinedCreateBaseQueryResult\
+
+```ts
+type DefinedCreateBaseQueryResult: Readable>;
+```
+
+Options for createBaseQuery with initialData
+
+## Type Parameters
+
+• **TData** = `unknown`
+
+• **TError** = `DefaultError`
+
+## Defined in
+
+[packages/svelte-query/src/types.ts:75](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/svelte-query/src/types.ts#L75)
diff --git a/docs/zh-hans/framework/svelte/reference/type-aliases/definedcreatequeryresult.md b/docs/zh-hans/framework/svelte/reference/type-aliases/definedcreatequeryresult.md
new file mode 100644
index 00000000000..4bb3ed64e54
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reference/type-aliases/definedcreatequeryresult.md
@@ -0,0 +1,24 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:20:31.009Z'
+id: DefinedCreateQueryResult
+title: DefinedCreateQueryResult
+---
+
+# Type Alias: DefinedCreateQueryResult\
+
+```ts
+type DefinedCreateQueryResult: DefinedCreateBaseQueryResult;
+```
+
+Options for createQuery with initialData
+
+## Type Parameters
+
+• **TData** = `unknown`
+
+• **TError** = `DefaultError`
+
+## Defined in
+
+[packages/svelte-query/src/types.ts:81](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/svelte-query/src/types.ts#L81)
diff --git a/docs/zh-hans/framework/svelte/reference/type-aliases/definedinitialdataoptions.md b/docs/zh-hans/framework/svelte/reference/type-aliases/definedinitialdataoptions.md
new file mode 100644
index 00000000000..56c0081fd6e
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reference/type-aliases/definedinitialdataoptions.md
@@ -0,0 +1,34 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:20:30.960Z'
+id: DefinedInitialDataOptions
+title: DefinedInitialDataOptions
+---
+
+# Type Alias: DefinedInitialDataOptions\
+
+```ts
+type DefinedInitialDataOptions: CreateQueryOptions & object;
+```
+
+## Type declaration
+
+### initialData
+
+```ts
+initialData: NonUndefinedGuard | () => NonUndefinedGuard;
+```
+
+## Type Parameters
+
+• **TQueryFnData** = `unknown`
+
+• **TError** = `DefaultError`
+
+• **TData** = `TQueryFnData`
+
+• **TQueryKey** _extends_ `QueryKey` = `QueryKey`
+
+## Defined in
+
+[packages/svelte-query/src/queryOptions.ts:15](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/svelte-query/src/queryOptions.ts#L15)
diff --git a/docs/zh-hans/framework/svelte/reference/type-aliases/mutationstateoptions.md b/docs/zh-hans/framework/svelte/reference/type-aliases/mutationstateoptions.md
new file mode 100644
index 00000000000..944aaba1253
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reference/type-aliases/mutationstateoptions.md
@@ -0,0 +1,44 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:20:30.908Z'
+id: MutationStateOptions
+title: MutationStateOptions
+---
+
+# Type Alias: MutationStateOptions\
+
+```ts
+type MutationStateOptions: object;
+```
+
+Options for useMutationState
+
+## Type Parameters
+
+• **TResult** = `MutationState`
+
+## Type declaration
+
+### filters?
+
+```ts
+optional filters: MutationFilters;
+```
+
+### select()?
+
+```ts
+optional select: (mutation) => TResult;
+```
+
+#### Parameters
+
+• **mutation**: `Mutation`\<`unknown`, `DefaultError`, `unknown`, `unknown`\>
+
+#### Returns
+
+`TResult`
+
+## Defined in
+
+[packages/svelte-query/src/types.ts:140](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/svelte-query/src/types.ts#L140)
diff --git a/docs/zh-hans/framework/svelte/reference/type-aliases/queriesoptions.md b/docs/zh-hans/framework/svelte/reference/type-aliases/queriesoptions.md
new file mode 100644
index 00000000000..820ed0e65aa
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reference/type-aliases/queriesoptions.md
@@ -0,0 +1,26 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:20:30.857Z'
+id: QueriesOptions
+title: QueriesOptions
+---
+
+# Type Alias: QueriesOptions\
+
+```ts
+type QueriesOptions: TDepth["length"] extends MAXIMUM_DEPTH ? QueryObserverOptionsForCreateQueries[] : T extends [] ? [] : T extends [infer Head] ? [...TResults, GetQueryObserverOptionsForCreateQueries] : T extends [infer Head, ...(infer Tails)] ? QueriesOptions<[...Tails], [...TResults, GetQueryObserverOptionsForCreateQueries], [...TDepth, 1]> : ReadonlyArray extends T ? T : T extends QueryObserverOptionsForCreateQueries[] ? QueryObserverOptionsForCreateQueries[] : QueryObserverOptionsForCreateQueries[];
+```
+
+QueriesOptions reducer recursively unwraps function arguments to infer/enforce type param
+
+## Type Parameters
+
+• **T** _extends_ `any`[]
+
+• **TResults** _extends_ `any`[] = []
+
+• **TDepth** _extends_ `ReadonlyArray`\<`number`\> = []
+
+## Defined in
+
+[packages/svelte-query/src/createQueries.ts:129](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/svelte-query/src/createQueries.ts#L129)
diff --git a/docs/zh-hans/framework/svelte/reference/type-aliases/queriesresults.md b/docs/zh-hans/framework/svelte/reference/type-aliases/queriesresults.md
new file mode 100644
index 00000000000..aba2599035f
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reference/type-aliases/queriesresults.md
@@ -0,0 +1,26 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:20:30.792Z'
+id: QueriesResults
+title: QueriesResults
+---
+
+# Type Alias: QueriesResults\
+
+```ts
+type QueriesResults: TDepth["length"] extends MAXIMUM_DEPTH ? QueryObserverResult[] : T extends [] ? [] : T extends [infer Head] ? [...TResults, GetCreateQueryResult] : T extends [infer Head, ...(infer Tails)] ? QueriesResults<[...Tails], [...TResults, GetCreateQueryResult], [...TDepth, 1]> : T extends QueryObserverOptionsForCreateQueries[] ? QueryObserverResult[] : QueryObserverResult[];
+```
+
+QueriesResults reducer recursively maps type param to results
+
+## Type Parameters
+
+• **T** _extends_ `any`[]
+
+• **TResults** _extends_ `any`[] = []
+
+• **TDepth** _extends_ `ReadonlyArray`\<`number`\> = []
+
+## Defined in
+
+[packages/svelte-query/src/createQueries.ts:171](https://github.com/TanStack/query/blob/dac5da5416b82b0be38a8fb34dde1fc6670f0a59/packages/svelte-query/src/createQueries.ts#L171)
diff --git a/docs/zh-hans/framework/svelte/reference/type-aliases/storeorval.md b/docs/zh-hans/framework/svelte/reference/type-aliases/storeorval.md
new file mode 100644
index 00000000000..a0e8ebbcb33
--- /dev/null
+++ b/docs/zh-hans/framework/svelte/reference/type-aliases/storeorval.md
@@ -0,0 +1,22 @@
+---
+source-updated-at: '2024-07-27T03:03:44.000Z'
+translation-updated-at: '2025-05-06T05:20:30.756Z'
+id: StoreOrVal
+title: StoreOrVal
+---
+
+# Type Alias: StoreOrVal\
+
+```ts
+type StoreOrVal: T | Readable