译零 TransZero · TanStack Query 中文文档
主站

useSuspenseInfiniteQuery

更新于 2026-11-02 Preact 查看英文原文 ↗
TypeScript
1function useSuspenseInfiniteQuery<TQueryFnData, TError = Error, TData = InfiniteData<TQueryFnData, unknown>, TQueryKey extends readonly unknown[] = readonly unknown[], TPageParam = unknown>(options: UseSuspenseInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>, queryClient?: QueryClient): UseSuspenseInfiniteQueryResult<TData, TError>;

定义于:packages/preact-query/src/useSuspenseInfiniteQuery.ts:122

useSuspenseInfiniteQuery 的选项与 useInfiniteQuery 相同,但不包括 throwOnError、enabled 和 placeholderData。

注意:取消(cancellation)功能不生效。

类型参数

TQueryFnData

TQueryFnData

TError

TError = Error

TData

TData = InfiniteData<TQueryFnData, unknown>

TQueryKey

TQueryKey extends readonly unknown[] = readonly unknown[]

TPageParam

TPageParam = unknown

参数

options

UseSuspenseInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>

要使用的 UseSuspenseInfiniteQueryOptions —— 与 useInfiniteQuery 的选项相同,但排除上述列出的几项。

options 属性

属性 类型 默认值 描述
gcTime? number undefined 未使用/非活跃缓存数据在内存中保留的毫秒数。当某个查询的缓存变为未使用或非活跃状态后,该缓存数据将在该时长后被垃圾回收。若指定了多个不同的垃圾回收时间,则取最长者生效。设为 Infinity 将禁用垃圾回收。默认为 5 * 60 * 1000(5 分钟),服务端渲染(SSR)期间则为 Infinity。注意:受 setTimeout 的 32 位有符号整数延时限制,最大允许时间为约 24 天——参见 timeoutManager.setTimeoutProvider 获取变通方案。
getNextPageParam (lastPage: TQueryFnData, allPages: TQueryFnData[], lastPageParam: TPageParam, allPageParams: TPageParam[]) => TPageParam | null | undefined undefined 此函数可用于自动获取无限查询的下一页游标。其返回值还将用于确定 hasNextPage 的值。
getPreviousPageParam? (firstPage: TQueryFnData, allPages: TQueryFnData[], firstPageParam: TPageParam, allPageParams: TPageParam[]) => TPageParam | null | undefined undefined 此函数可用于自动获取无限查询的上一页游标。其返回值还将用于确定 hasPreviousPage 的值。
initialData? | InfiniteData<TQueryFnData, TPageParam> | (() => | InfiniteData<TQueryFnData, TPageParam> | undefined) undefined 若设置该值,它将作为查询缓存的初始数据(前提是该查询尚未创建或缓存)。若设为函数,则该函数将在共享/根查询初始化期间仅调用一次,且需同步返回初始数据。初始数据默认视为过期,除非已设置 staleTime。initialData 会被持久化到缓存中。
initialDataUpdatedAt? number | (() => number | undefined) undefined 若设置该值,它将作为 initialData 本身最近一次更新的时间(毫秒)。
initialPageParam TPageParam undefined 当无限查询尚无任何页时,起始页码参数。它将作为 queryFn 的 pageParam 参数传入第一页;后续每一页则使用 getNextPageParam 或 getPreviousPageParam 返回的值。该选项仅在查询尚无页时生效;一旦存在第一页,重新拉取将从该页自身的参数开始。
maxPages? number undefined 无限查询数据中最多存储的页数。
meta? Record<string, unknown> undefined 存储在每个查询上的额外载荷。可利用此属性传递可在其他位置使用的附加信息。
networkMode? "online" | "always" | "offlineFirst" 'online' 控制查询是否允许基于当前网络连接状态运行。详见 网络模式。
notifyOnChangeProps? | ( | "error" | "data" | "isError" | "isPending" | "isLoading" | "isLoadingError" | "isRefetchError" | "isSuccess" | "isPlaceholderData" | "status" | "dataUpdatedAt" | "errorUpdatedAt" | "failureCount" | "failureReason" | "errorUpdateCount" | "isFetched" | "isFetchedAfterMount" | "isFetching" | "isInitialLoading" | "isPaused" | "isRefetching" | "isStale" | "isEnabled" | "refetch" | "fetchStatus" | "fetchNextPage" | "fetchPreviousPage" | "hasNextPage" | "hasPreviousPage" | "isFetchNextPageError" | "isFetchingNextPage" | "isFetchPreviousPageError" | "isFetchingPreviousPage")[] | "all" | (() => | "all" | ( | "error" | "data" | "isError" | "isPending" | "isLoading" | "isLoadingError" | "isRefetchError" | "isSuccess" | "isPlaceholderData" | "status" | "dataUpdatedAt" | "errorUpdatedAt" | "failureCount" | "failureReason" | "errorUpdateCount" | "isFetched" | "isFetchedAfterMount" | "isFetching" | "isInitialLoading" | "isPaused" | "isRefetching" | "isStale" | "isEnabled" | "refetch" | "fetchStatus" | "fetchNextPage" | "fetchPreviousPage" | "hasNextPage" | "hasPreviousPage" | "isFetchNextPageError" | "isFetchingNextPage" | "isFetchPreviousPageError" | "isFetchingPreviousPage")[] | undefined) undefined 若设置该值,组件仅在所列属性中任一发生变化时才重新渲染。设为 ['data', 'error'] 时,组件仅在 data 或 error 属性变化时重新渲染。设为 'all' 时,组件将在任意查询更新时重新渲染。设为函数时,该函数将被执行以计算属性列表。默认为 undefined,此时会自动追踪属性访问,组件仅在任一被追踪属性变化时重新渲染。
persister? (queryFn: (context: QueryFunctionContext<NoInfer<TQueryKey>, TPageParam>) => TQueryFnData | Promise<TQueryFnData>, context: object, query: Query) => TQueryFnData | Promise<TQueryFnData> undefined 此选项可用于将查询结果持久化至外部存储,从而绕过实际调用 queryFn 的需要。适用于跨服务端/客户端边界持久化查询数据等场景。
queryFn? (context: QueryFunctionContext<TQueryKey, TPageParam>) => TQueryFnData | Promise<TQueryFnData> undefined 此处不允许使用 skipToken —— Suspense Hook 无法渲染“禁用”状态,因此必须始终提供查询函数,除非已定义默认查询函数。
queryHash? string undefined queryKey 的哈希形式,由 queryKeyHashFn(或默认哈希函数)计算得出。该哈希值将作为内部实际缓存键使用。
queryKey TQueryKey & object undefined 此查询所用的查询键。查询键将被哈希为稳定哈希值。更多信息请参阅 查询键。只要 enabled 未设为 false,该键变化时查询将自动更新。
queryKeyHashFn? (queryKey: TQueryKey) => string undefined 若指定,该函数将用于将 queryKey 哈希为字符串。
refetchInterval? | number | false | ((query: Query<TQueryFnData, TError, InfiniteData<TQueryFnData, TPageParam>, TQueryKey>) => number | false | undefined) false 若设为数字,查询将以该毫秒频率持续重新拉取。若设为函数,该函数将接收最新数据和查询对象,以计算频率。
refetchIntervalInBackground? boolean false 若设为 true,查询将在标签页/窗口处于后台时继续重新拉取。
refetchOnMount? | boolean | "always" | ((query: Query<TQueryFnData, TError, InfiniteData<TQueryFnData, TPageParam>, TQueryKey>) => boolean | "always") true 若设为 true,当数据过期时,查询将在挂载时重新拉取。若设为 false,将禁用同一查询的额外实例触发后台重新拉取。若设为 'always',查询将在每次挂载时始终重新拉取(除非使用了 staleTime: 'static')。若设为函数,该函数将接收最新数据和查询对象,以计算该值。
refetchOnReconnect? | boolean | "always" | ((query: Query<TQueryFnData, TError, InfiniteData<TQueryFnData, TPageParam>, TQueryKey>) => boolean | "always") undefined 若设为 true,当数据过期时,查询将在网络重连时重新拉取。若设为 false,查询在网络重连时不会重新拉取。若设为 'always',查询将在每次网络重连时始终重新拉取(除非使用了 staleTime: 'static')。若设为函数,该函数将接收最新数据和查询对象,以计算该值。默认为 true,除非 networkMode 为 'always'。
refetchOnWindowFocus? | boolean | "always" | ((query: Query<TQueryFnData, TError, InfiniteData<TQueryFnData, TPageParam>, TQueryKey>) => boolean | "always") true 若设为 true,当数据过期时,查询将在窗口获得焦点时重新拉取。若设为 false,查询在窗口获得焦点时不会重新拉取。若设为 'always',查询将在每次窗口获得焦点时始终重新拉取(除非使用了 staleTime: 'static')。若设为函数,该函数将接收最新数据和查询对象,以计算该值。
retry? | number | false | true | ((failureCount: number, error: TError) => boolean) undefined 若为 false,失败查询默认不重试。若为 true,失败查询将无限重试。若设为整数(例如 3),失败查询将重试直至失败次数达到该数值。若设为函数 (failureCount, error) => boolean,失败查询将重试直至该函数返回 false。客户端默认为 3,服务端默认为 0。
retryDelay? number | ((failureCount: number, error: TError) => number) undefined 该函数接收一个 retryAttempt 整数和实际错误对象,并返回下次尝试前应延迟的毫秒数。类似 attempt => Math.min(attempt > 1 ? 2 ** attempt * 1000 : 1000, 30 * 1000) 的函数实现指数退避;类似 attempt => attempt * 1000 的函数实现线性退避。默认为一个应用指数退避的函数,上限为 30 秒。
retryOnMount? | false | true | ((query: Query<TQueryFnData, TError, InfiniteData<TQueryFnData, TPageParam>, TQueryKey>) => boolean) true 若设为 false,当查询包含错误时,其在挂载时不会重试。若设为函数,该函数将接收查询对象以计算该值。
select? (data: InfiniteData) => TData undefined 此选项可用于转换或选取查询函数返回数据的一部分。它影响返回的 data 值,但不影响存储在查询缓存中的内容。select 函数仅在 data 发生变化,或 select 函数自身引用发生变化时执行。为优化性能,请对函数进行记忆化处理,使其引用在多次调用中保持稳定。
staleTime? | number | "static" | ((query: Query<TQueryFnData, TError, InfiniteData<TQueryFnData, TPageParam>, TQueryKey>) => number | "static") 0 数据被视为过期前的毫秒数。若设为 Infinity,数据将永不被视为过期。若设为 'static',数据将永不被视为过期。若设为函数,该函数将接收查询对象以计算 staleTime。
structuralSharing? boolean | ((oldData: unknown, newData: unknown) => unknown) true 设为 false 可禁用查询结果之间的结构共享。设为函数时,该函数接收旧数据与新数据,并返回同类型解析后的数据,以实现自定义结构共享逻辑。
subscribed? boolean true 设为 false 可取消此观察者对查询缓存更新的订阅。

queryClient?

QueryClient

使用此选项可指定自定义的 QueryClient。否则,将使用离当前组件最近的上下文所提供的 QueryClient。

返回值

UseSuspenseInfiniteQueryResult<TData, TError>

该对象与 useInfiniteQuery 相同,但保证 data 已定义,不包含 isPlaceholderData,且 status 的类型为 success 或 error(相应派生标志已正确设置)。

返回结果属性

基于 InfiniteQueryObserverBaseResult 构建。具体变更内容请参见上方类型定义。

注意事项

同一组件内多个启用 Suspense 的查询调用会串行挂起,导致请求瀑布(request waterfall)——每个查询都会阻塞渲染,直至其解析完成,因此下一个查询甚至无法开始拉取。在 Suspense 下,无法并行执行多个无限查询。此外请注意,诸如 fetchNextPage 这类命令式拉取调用可能干扰默认的重新拉取行为,从而导致数据过时。请确保仅在响应用户操作时调用这些函数,或添加类似 hasNextPage && !isFetching 的条件判断。

参阅

如需非 Suspense 版本的该 Hook,请参阅 useInfiniteQuery。

示例

若拉取失败且尚未缓存任何数据,则会抛出查询错误,因此 <Suspense> 外层必须包裹错误边界(error boundary)。而失败的后台重新拉取则会继续渲染已缓存的数据。可使用 QueryErrorResetBoundary 让用户在发生此类错误后重试:

TypeScript
1import { Suspense } from 'preact/compat'2import { useErrorBoundary } from 'preact/hooks'3import {4  QueryErrorResetBoundary,5  useSuspenseInfiniteQuery,6} from '@tanstack/preact-query'7import type { ComponentChildren } from 'preact'8 9function Projects() {10  // `data` is guaranteed to be defined here — no `isPending` check needed.11  const { data, fetchNextPage, hasNextPage, isFetching, isFetchingNextPage } =12    useSuspenseInfiniteQuery({13      queryKey: ['projects'],14      queryFn: ({ pageParam }) => fetchProjects(pageParam),15      initialPageParam: 0,16      getNextPageParam: (lastPage) => lastPage.nextId,17    })18 19  return (20    <div>21      <ul>22        {data.pages.map((page) =>23          page.projects.map((project) => <li key={project.id}>{project.name}</li>),24        )}25      </ul>26      <button27        onClick={() => fetchNextPage()}28        disabled={!hasNextPage || isFetching}29      >30        {isFetchingNextPage31          ? 'Loading more...'32          : hasNextPage33            ? 'Load More'34            : 'Nothing more to load'}35      </button>36    </div>37  )38}39 40function App() {41  return (42    <QueryErrorResetBoundary>43      {({ reset }) => (44        <ErrorBoundary45          onReset={reset}46          fallbackRender={({ resetErrorBoundary }) => (47            <div>48              There was an error!49              <button onClick={() => resetErrorBoundary()}>Try again</button>50            </div>51          )}52        >53          <Suspense fallback={<h1>Loading projects...</h1>}>54            <Projects />55          </Suspense>56        </ErrorBoundary>57      )}58    </QueryErrorResetBoundary>59  )60}61 62function ErrorBoundary({63  children,64  onReset,65  fallbackRender,66}: {67  children: ComponentChildren68  onReset: () => void69  fallbackRender: (props: {70    error: Error71    resetErrorBoundary: () => void72  }) => ComponentChildren73}) {74  const [error, resetErrorBoundary] = useErrorBoundary(() => onReset())75 76  if (error) return fallbackRender({ error, resetErrorBoundary })77 78  return children79}

本页为 TanStack Query 文档(Preact 版)的非官方中文翻译,原文由上游团队维护,遵循 MIT 许可。 译文如有偏差,以英文原文为准。

译自上游 59d11de