Suspense
sup
Suspense(挂起)
React Query 也可以与 React 的 Suspense for Data Fetching API 一起使用。对此,React Query 提供了一些专门的 Hook:
useSuspenseQuery
useSuspenseInfiniteQuery
useSuspenseQueries
此外,你还可以使用 useQuery().promise
和 React.use()
(实验性功能)。
在 Suspense 模式下,状态(status)和错误对象(error)不再需要,它们由 React.Suspense 组件 处理(包括使用 fallback
属性提供回退 UI,并利用 React 错误边界(Error Boundaries) 捕获错误)。
请阅读 Resetting Error Boundaries 以及 Suspense 示例 了解如何正确设置 Suspense 模式。
如果你希望 Mutation(变更) 也像 Query 一样将错误抛给最近的 Error Boundary,你可以设置 throwOnError: true
。
启用 Suspense 模式
在 TypeScript 中,这种方式很好用,因为 data
保证是已定义的(因为错误和加载状态已经由 Suspense 和 Error Boundary 处理)。
⚠ 注意:
你 无法 动态开启/关闭该 Query(
enabled
选项不可用)。placeholderData
在 Suspense 模式下不可用。避免 UI 在更新时被
fallback
取代,你可以使用startTransition
包裹 QueryKey 变化的更新。
throwOnError
的默认行为
throwOnError
的默认行为并 不是所有错误 都会默认抛给最近的 Error Boundary,只有当 Query 没有可用数据 时,错误才会被抛出:
由于 throwOnError
不能被修改(否则 data
可能变为 undefined
),如果你希望所有错误都被 Error Boundary 处理,你需要手动抛出错误:
重置错误边界(Resetting Error Boundaries)
无论你是 使用 Suspense 还是 设置 throwOnError
,当错误发生后,你需要一种方法来 重置错误状态 并重新尝试请求数据。
React Query 提供了两种方式来 重置 Query 的错误状态:
1. QueryErrorResetBoundary
组件
QueryErrorResetBoundary
组件该组件会 重置其内部所有 Query 的错误状态:
2. useQueryErrorResetBoundary
Hook
useQueryErrorResetBoundary
Hook这个 Hook 会 重置最近的 QueryErrorResetBoundary
内部的错误状态,如果没有 QueryErrorResetBoundary
,则会 全局重置错误状态:
Fetch-on-render vs Render-as-you-fetch
React Query 在 Suspense 模式下 默认使用 Fetch-on-render,这意味着:
组件 在挂载时 触发数据请求。
组件会 挂起(Suspend),直到数据加载完成。
如果你希望 提前加载数据,可以使用 预取(Prefetching) 技术,在 路由回调 或 用户交互事件 中 预加载 Query,从而实现 Render-as-you-fetch 模型。
在服务器端使用 Suspense(Streaming)
如果你使用 Next.js,可以使用 @tanstack/react-query-next-experimental
来支持 服务端 Suspense Streaming。
这可以让你在 客户端组件 中调用 useSuspenseQuery
,并在服务器端预取数据,结果会被 流式传输(Streaming) 到客户端。
如何启用 Streaming
更多信息,请查看 Next.js Suspense Streaming 示例 和 高级渲染 & Hydration 指南。
使用 useQuery().promise
和 React.use()
(实验性)
useQuery().promise
和 React.use()
(实验性)最后更新于
这有帮助吗?