useSuspenseQueries
概述
1function useSuspenseQueries<T extends any[], TCombinedResult = T extends [] ? [] : T extends [Head] ? [GetUseSuspenseQueryResult<Head>] : T extends [Head, ...Tails[]] ? [...Tails[]] extends [] ? [] : [...Tails[]] extends [Head] ? [GetUseSuspenseQueryResult<Head>, GetUseSuspenseQueryResult<Head>] : [...Tails[]] extends [Head, ...Tails[]] ? [...Tails[]] extends [] ? [] : [...Tails[]] extends [Head] ? [GetUseSuspenseQueryResult<Head>, GetUseSuspenseQueryResult<Head>, GetUseSuspenseQueryResult<Head>] : [...Tails[]] extends [Head, ...Tails[]] ? [...(...)[]] extends [] ? [] : ... extends ... ? ... : ... : [...{ [K in (...)]: (...) }[]] : [...{ [K in string | number | symbol]: GetUseSuspenseQueryResult<Tails[K]> }[]] : { [K in string | number | symbol]: GetUseSuspenseQueryResult<T[K]> }>(options: object, queryClient?: QueryClient): TCombinedResult;2function useSuspenseQueries<T extends any[], TCombinedResult = T extends [] ? [] : T extends [Head] ? [GetUseSuspenseQueryResult<Head>] : T extends [Head, ...Tails[]] ? [...Tails[]] extends [] ? [] : [...Tails[]] extends [Head] ? [GetUseSuspenseQueryResult<Head>, GetUseSuspenseQueryResult<Head>] : [...Tails[]] extends [Head, ...Tails[]] ? [...Tails[]] extends [] ? [] : [...Tails[]] extends [Head] ? [GetUseSuspenseQueryResult<Head>, GetUseSuspenseQueryResult<Head>, GetUseSuspenseQueryResult<Head>] : [...Tails[]] extends [Head, ...Tails[]] ? [...(...)[]] extends [] ? [] : ... extends ... ? ... : ... : [...{ [K in (...)]: (...) }[]] : [...{ [K in string | number | symbol]: GetUseSuspenseQueryResult<Tails[K]> }[]] : { [K in string | number | symbol]: GetUseSuspenseQueryResult<T[K]> }>(options: object, queryClient?: QueryClient): TCombinedResult;{ queries, combine }→TCombinedResult:useSuspenseQueries的选项与useQueries相同,但不支持顶层subscribed选项,且每个query均不可配置throwOnError、enabled或placeholderData。{ queries, combine }→TCombinedResult:useSuspenseQueries的选项与useQueries相同,但不支持顶层subscribed选项,且每个query均不可配置throwOnError、enabled或placeholderData。
调用签名
1function useSuspenseQueries<T extends any[], TCombinedResult = T extends [] ? [] : T extends [Head] ? [GetUseSuspenseQueryResult<Head>] : T extends [Head, ...Tails[]] ? [...Tails[]] extends [] ? [] : [...Tails[]] extends [Head] ? [GetUseSuspenseQueryResult<Head>, GetUseSuspenseQueryResult<Head>] : [...Tails[]] extends [Head, ...Tails[]] ? [...Tails[]] extends [] ? [] : [...Tails[]] extends [Head] ? [GetUseSuspenseQueryResult<Head>, GetUseSuspenseQueryResult<Head>, GetUseSuspenseQueryResult<Head>] : [...Tails[]] extends [Head, ...Tails[]] ? [...(...)[]] extends [] ? [] : ... extends ... ? ... : ... : [...{ [K in (...)]: (...) }[]] : [...{ [K in string | number | symbol]: GetUseSuspenseQueryResult<Tails[K]> }[]] : { [K in string | number | symbol]: GetUseSuspenseQueryResult<T[K]> }>(options: object, queryClient?: QueryClient): TCombinedResult;定义于:packages/react-query/src/useSuspenseQueries.ts:347
useSuspenseQueries 的选项与 useQueries 相同,但不支持顶层 subscribed 选项,且每个 query 均不可配置 throwOnError、enabled 或 placeholderData。
类型参数
T
T extends any[]
TCombinedResult
TCombinedResult = T extends [] ? [] : T extends [Head] ? [GetUseSuspenseQueryResult<Head>] : T extends [Head, ...Tails[]] ? [...Tails[]] extends [] ? [] : [...Tails[]] extends [Head] ? [GetUseSuspenseQueryResult<Head>, GetUseSuspenseQueryResult<Head>] : [...Tails[]] extends [Head, ...Tails[]] ? [...Tails[]] extends [] ? [] : [...(...)[]] extends [...] ? [..., ..., ...] : ... extends ... ? ... : ... : [...{ [K in (...)]: (...) }[]] : [...{ [K in string | number | symbol]: GetUseSuspenseQueryResult<Tails[K]> }[]] : { [K in string | number | symbol]: GetUseSuspenseQueryResult<T[K]> }
参数
options
在 Suspense 中运行的 queries 数组,以及一个可选的 combine 函数。
combine?
(result: T extends [] ? [] : T extends [Head] ? [GetUseSuspenseQueryResult<Head>] : T extends [Head, ...Tails[]] ? [...Tails[]] extends [] ? [] : [...Tails[]] extends [Head] ? [GetUseSuspenseQueryResult<Head>, GetUseSuspenseQueryResult<Head>] : [...Tails[]] extends [Head, ...Tails[]] ? [...(...)[]] extends [] ? [] : ... extends ... ? ... : ... : [...{ [K in (...)]: (...) }[]] : { [K in string | number | symbol]: GetUseSuspenseQueryResult<T[K]> }) => TCombinedResult
使用此函数将各查询结果合并为单个值。该结果将在结构上共享,以尽可能保持引用稳定性。
queries
| readonly [T extends [] ? [] : T extends [Head] ? [GetUseSuspenseQueryOptions<Head>] : T extends [Head, ...Tails[]] ? [...Tails[]] extends [] ? [] : [...Tails[]] extends [Head] ? [GetUseSuspenseQueryOptions<Head>, GetUseSuspenseQueryOptions<Head>] : [...Tails[]] extends [Head, ...Tails[]] ? [...(...)[]] extends [] ? [] : ... extends ... ? ... : ... : ...[] extends [...(...)[]] ? [...(...)[]] : ... extends ... ? ... : ... : unknown[] extends T ? T : T extends UseSuspenseQueryOptions<TQueryFnData, TError, TData, TQueryKey>[] ? UseSuspenseQueryOptions<TQueryFnData, TError, TData, TQueryKey>[] : UseSuspenseQueryOptions<unknown, Error, unknown, readonly ...[]>[]]
| readonly [{ [K in string | number | symbol]: GetUseSuspenseQueryOptions<T[K]> }]
一个查询选项对象数组,其结构与 useSuspenseQuery 完全相同。
queryClient?
使用此参数传入自定义 QueryClient;否则将使用离组件最近的上下文中的 QueryClient。
返回值
TCombinedResult
其结构与 useQueries 相同,但对每个 query,data 必然已定义,isPlaceholderData 不会出现,而 status 只能是 success 或 error(相应派生标志将被正确设置)。
注意事项:组件仅在所有查询加载完成后才会重新挂载。因此,若在全部查询完成前某个查询已变为过期,则该查询会在重新挂载时再次拉取。为避免此情况,请确保设置足够高的 staleTime。取消功能不生效。
示例
若拉取失败且尚无缓存数据,则会抛出查询错误,因此 <Suspense> 外围必须包裹错误边界。后台重新拉取失败时则继续渲染缓存数据。可使用 QueryErrorResetBoundary 让用户在发生此类错误后重试:
1import { Suspense } from 'react'2import { ErrorBoundary } from 'react-error-boundary'3import {4 QueryErrorResetBoundary,5 useSuspenseQueries,6} from '@tanstack/react-query'7 8function Posts({ ids }: { ids: Array<number> }) {9 // Every result is guaranteed to be defined — no per-query `isPending` check needed.10 const postQueries = useSuspenseQueries({11 queries: ids.map((id) => ({12 queryKey: ['post', id],13 queryFn: () => fetchPost(id),14 })),15 })16 17 return (18 <ul>19 {postQueries.map((query) => (20 <li key={query.data.id}>{query.data.title}</li>21 ))}22 </ul>23 )24}25 26function App() {27 return (28 <QueryErrorResetBoundary>29 {({ reset }) => (30 <ErrorBoundary31 onReset={reset}32 fallbackRender={({ resetErrorBoundary }) => (33 <div>34 There was an error!35 <button onClick={() => resetErrorBoundary()}>Try again</button>36 </div>37 )}38 >39 <Suspense fallback={<h1>Loading posts...</h1>}>40 <Posts ids={[1, 2, 3]} />41 </Suspense>42 </ErrorBoundary>43 )}44 </QueryErrorResetBoundary>45 )46}多个不同查询 — 使用 useSuspenseQueries 替代多次调用 useSuspenseQuery,使它们并行拉取,而非依次挂起:
1import { Suspense } from 'react'2import { ErrorBoundary } from 'react-error-boundary'3import {4 QueryErrorResetBoundary,5 useSuspenseQueries,6} from '@tanstack/react-query'7 8function Dashboard() {9 const [usersQuery, teamsQuery, projectsQuery] = useSuspenseQueries({10 queries: [11 { queryKey: ['users'], queryFn: fetchUsers },12 { queryKey: ['teams'], queryFn: fetchTeams },13 { queryKey: ['projects'], queryFn: fetchProjects },14 ],15 })16 17 return (18 <div>19 <UserList users={usersQuery.data} />20 <TeamList teams={teamsQuery.data} />21 <ProjectList projects={projectsQuery.data} />22 </div>23 )24}25 26function App() {27 return (28 <QueryErrorResetBoundary>29 {({ reset }) => (30 <ErrorBoundary31 onReset={reset}32 fallbackRender={({ resetErrorBoundary }) => (33 <div>34 There was an error!35 <button onClick={() => resetErrorBoundary()}>Try again</button>36 </div>37 )}38 >39 <Suspense fallback={<h1>Loading dashboard...</h1>}>40 <Dashboard />41 </Suspense>42 </ErrorBoundary>43 )}44 </QueryErrorResetBoundary>45 )46}combine 将结果合并为单个布尔值,因此 Refresh 仅在该布尔值变化时重新渲染,而非每次单个查询更新时都触发。此重载是唯一接受 combine 的版本:
1import { Suspense } from 'react'2import { ErrorBoundary } from 'react-error-boundary'3import {4 QueryErrorResetBoundary,5 useSuspenseQueries,6} from '@tanstack/react-query'7 8function Refresh() {9 const anyFetching = useSuspenseQueries({10 queries: [11 { queryKey: ['users'], queryFn: fetchUsers },12 { queryKey: ['teams'], queryFn: fetchTeams },13 ],14 combine: (results) => results.some((result) => result.isFetching),15 })16 17 return anyFetching ? <span>Refreshing…</span> : null18}19 20function App() {21 return (22 <QueryErrorResetBoundary>23 {({ reset }) => (24 <ErrorBoundary25 onReset={reset}26 fallbackRender={({ resetErrorBoundary }) => (27 <div>28 There was an error!29 <button onClick={() => resetErrorBoundary()}>Try again</button>30 </div>31 )}32 >33 <Suspense fallback={<h1>Loading dashboard...</h1>}>34 <Refresh />35 </Suspense>36 </ErrorBoundary>37 )}38 </QueryErrorResetBoundary>39 )40}调用签名
1function useSuspenseQueries<T extends any[], TCombinedResult = T extends [] ? [] : T extends [Head] ? [GetUseSuspenseQueryResult<Head>] : T extends [Head, ...Tails[]] ? [...Tails[]] extends [] ? [] : [...Tails[]] extends [Head] ? [GetUseSuspenseQueryResult<Head>, GetUseSuspenseQueryResult<Head>] : [...Tails[]] extends [Head, ...Tails[]] ? [...Tails[]] extends [] ? [] : [...Tails[]] extends [Head] ? [GetUseSuspenseQueryResult<Head>, GetUseSuspenseQueryResult<Head>, GetUseSuspenseQueryResult<Head>] : [...Tails[]] extends [Head, ...Tails[]] ? [...(...)[]] extends [] ? [] : ... extends ... ? ... : ... : [...{ [K in (...)]: (...) }[]] : [...{ [K in string | number | symbol]: GetUseSuspenseQueryResult<Tails[K]> }[]] : { [K in string | number | symbol]: GetUseSuspenseQueryResult<T[K]> }>(options: object, queryClient?: QueryClient): TCombinedResult;定义于:packages/react-query/src/useSuspenseQueries.ts:484
useSuspenseQueries 的选项与 useQueries 相同,但不支持顶层 subscribed 选项,且每个 query 均不可配置 throwOnError、enabled 或 placeholderData。
类型参数
T
T extends any[]
TCombinedResult
TCombinedResult = T extends [] ? [] : T extends [Head] ? [GetUseSuspenseQueryResult<Head>] : T extends [Head, ...Tails[]] ? [...Tails[]] extends [] ? [] : [...Tails[]] extends [Head] ? [GetUseSuspenseQueryResult<Head>, GetUseSuspenseQueryResult<Head>] : [...Tails[]] extends [Head, ...Tails[]] ? [...Tails[]] extends [] ? [] : [...(...)[]] extends [...] ? [..., ..., ...] : ... extends ... ? ... : ... : [...{ [K in (...)]: (...) }[]] : [...{ [K in string | number | symbol]: GetUseSuspenseQueryResult<Tails[K]> }[]] : { [K in string | number | symbol]: GetUseSuspenseQueryResult<T[K]> }
参数
options
在 Suspense 中运行的 queries 数组,以及一个可选的 combine 函数。
combine?
(result: T extends [] ? [] : T extends [Head] ? [GetUseSuspenseQueryResult<Head>] : T extends [Head, ...Tails[]] ? [...Tails[]] extends [] ? [] : [...Tails[]] extends [Head] ? [GetUseSuspenseQueryResult<Head>, GetUseSuspenseQueryResult<Head>] : [...Tails[]] extends [Head, ...Tails[]] ? [...(...)[]] extends [] ? [] : ... extends ... ? ... : ... : [...{ [K in (...)]: (...) }[]] : { [K in string | number | symbol]: GetUseSuspenseQueryResult<T[K]> }) => TCombinedResult
使用此函数将各查询结果合并为单个值。该结果将在结构上共享,以尽可能保持引用稳定性。
queries
readonly [T extends [] ? [] : T extends [Head] ? [GetUseSuspenseQueryOptions<Head>] : T extends [Head, ...Tails[]] ? [...Tails[]] extends [] ? [] : [...Tails[]] extends [Head] ? [GetUseSuspenseQueryOptions<Head>, GetUseSuspenseQueryOptions<Head>] : [...Tails[]] extends [Head, ...Tails[]] ? [...Tails[]] extends [] ? [] : [...(...)[]] extends [...] ? [..., ..., ...] : ... extends ... ? ... : ... : unknown[] extends [...Tails[]] ? [...Tails[]] : [...(...)[]] extends ...[] ? ...[] : ...[] : unknown[] extends T ? T : T extends UseSuspenseQueryOptions<TQueryFnData, TError, TData, TQueryKey>[] ? UseSuspenseQueryOptions<TQueryFnData, TError, TData, TQueryKey>[] : UseSuspenseQueryOptions<unknown, Error, unknown, readonly unknown[]>[]]
一个查询选项对象数组,其结构与 useSuspenseQuery 完全相同。
queryClient?
使用此参数传入自定义 QueryClient;否则将使用离组件最近的上下文中的 QueryClient。
返回值
TCombinedResult
其结构与 useQueries 相同,但对每个 query,data 必然已定义,isPlaceholderData 不会出现,而 status 只能是 success 或 error(相应派生标志将被正确设置)。
注意事项:组件仅在所有查询加载完成后才会重新挂载。因此,若在全部查询完成前某个查询已变为过期,则该查询会在重新挂载时再次拉取。为避免此情况,请确保设置足够高的 staleTime。取消功能不生效。
示例
若拉取失败且尚无缓存数据,则会抛出查询错误,因此 <Suspense> 外围必须包裹错误边界。后台重新拉取失败时则继续渲染缓存数据。可使用 QueryErrorResetBoundary 让用户在发生此类错误后重试:
1import { Suspense } from 'react'2import { ErrorBoundary } from 'react-error-boundary'3import {4 QueryErrorResetBoundary,5 useSuspenseQueries,6} from '@tanstack/react-query'7 8function Posts({ ids }: { ids: Array<number> }) {9 // Every result is guaranteed to be defined — no per-query `isPending` check needed.10 const postQueries = useSuspenseQueries({11 queries: ids.map((id) => ({12 queryKey: ['post', id],13 queryFn: () => fetchPost(id),14 })),15 })16 17 return (18 <ul>19 {postQueries.map((query) => (20 <li key={query.data.id}>{query.data.title}</li>21 ))}22 </ul>23 )24}25 26function App() {27 return (28 <QueryErrorResetBoundary>29 {({ reset }) => (30 <ErrorBoundary31 onReset={reset}32 fallbackRender={({ resetErrorBoundary }) => (33 <div>34 There was an error!35 <button onClick={() => resetErrorBoundary()}>Try again</button>36 </div>37 )}38 >39 <Suspense fallback={<h1>Loading posts...</h1>}>40 <Posts ids={[1, 2, 3]} />41 </Suspense>42 </ErrorBoundary>43 )}44 </QueryErrorResetBoundary>45 )46}多个不同查询 — 使用 useSuspenseQueries 替代多次调用 useSuspenseQuery,使它们并行拉取,而非依次挂起:
1import { Suspense } from 'react'2import { ErrorBoundary } from 'react-error-boundary'3import {4 QueryErrorResetBoundary,5 useSuspenseQueries,6} from '@tanstack/react-query'7 8function Dashboard() {9 const [usersQuery, teamsQuery, projectsQuery] = useSuspenseQueries({10 queries: [11 { queryKey: ['users'], queryFn: fetchUsers },12 { queryKey: ['teams'], queryFn: fetchTeams },13 { queryKey: ['projects'], queryFn: fetchProjects },14 ],15 })16 17 return (18 <div>19 <UserList users={usersQuery.data} />20 <TeamList teams={teamsQuery.data} />21 <ProjectList projects={projectsQuery.data} />22 </div>23 )24}25 26function App() {27 return (28 <QueryErrorResetBoundary>29 {({ reset }) => (30 <ErrorBoundary31 onReset={reset}32 fallbackRender={({ resetErrorBoundary }) => (33 <div>34 There was an error!35 <button onClick={() => resetErrorBoundary()}>Try again</button>36 </div>37 )}38 >39 <Suspense fallback={<h1>Loading dashboard...</h1>}>40 <Dashboard />41 </Suspense>42 </ErrorBoundary>43 )}44 </QueryErrorResetBoundary>45 )46}参数
options
在 Suspense 中运行的 queries 数组,以及一个可选的 combine 函数。
combine?
(result: T extends [] ? [] : T extends [Head] ? [GetUseSuspenseQueryResult<Head>] : T extends [Head, ...Tails[]] ? [...Tails[]] extends [] ? [] : [...Tails[]] extends [Head] ? [GetUseSuspenseQueryResult<Head>, GetUseSuspenseQueryResult<Head>] : [...Tails[]] extends [Head, ...Tails[]] ? [...(...)[]] extends [] ? [] : ... extends ... ? ... : ... : [...{ [K in (...)]: (...) }[]] : { [K in string | number | symbol]: GetUseSuspenseQueryResult<T[K]> }) => TCombinedResult
使用此函数将各查询结果合并为单个值。该结果将在结构上共享,以尽可能保持引用稳定性。
queries
readonly [T extends [] ? [] : T extends [Head] ? [GetUseSuspenseQueryOptions<Head>] : T extends [Head, ...Tails[]] ? [...Tails[]] extends [] ? [] : [...Tails[]] extends [Head] ? [GetUseSuspenseQueryOptions<Head>, GetUseSuspenseQueryOptions<Head>] : [...Tails[]] extends [Head, ...Tails[]] ? [...Tails[]] extends [] ? [] : [...(...)[]] extends [...] ? [..., ..., ...] : ... extends ... ? ... : ... : unknown[] extends [...Tails[]] ? [...Tails[]] : [...(...)[]] extends ...[] ? ...[] : ...[] : unknown[] extends T ? T : T extends UseSuspenseQueryOptions<TQueryFnData, TError, TData, TQueryKey>[] ? UseSuspenseQueryOptions<TQueryFnData, TError, TData, TQueryKey>[] : UseSuspenseQueryOptions<unknown, Error, unknown, readonly unknown[]>[]]
一个查询选项对象数组,其结构与 useSuspenseQuery 完全相同。
queryClient?
使用此参数传入自定义 QueryClient;否则将使用离组件最近的上下文中的 QueryClient。
返回值
TCombinedResult
其结构与 useQueries 相同,但对每个 query,data 必然已定义,isPlaceholderData 不会出现,而 status 只能是 success 或 error(相应派生标志将被正确设置)。
注意事项:组件仅在所有查询加载完成后才会重新挂载。因此,若在全部查询完成前某个查询已变为过期,则该查询会在重新挂载时再次拉取。为避免此情况,请确保设置足够高的 staleTime。取消功能不生效。