ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Preact Query 的 UseSuspenseInfiniteQueryResult 返回类型全解析(TanStack Query)

Preact Query 的 UseSuspenseInfiniteQueryResult 返回类型全解析(TanStack Query) Preact Query 的 UseSuspenseInfiniteQueryResult 返回类型全解析TanStack Query【免费下载链接】query Powerful asynchronous state management, server-state utilities and data fetching for the web. TS/JS, React Query, Solid Query, Svelte Query and Vue Query.项目地址: https://gitcode.com/GitHub_Trending/qu/queryUseSuspenseInfiniteQueryResult是 TanStack Query 中 Preact 适配层专为useSuspenseInfiniteQuery设计的结果类型它基于 core 层的DefinedInfiniteQueryObserverResult派生而来并额外删除了isPlaceholderData字段。读懂这个类型别名等于同时理清了无限查询的确定性数据形态与Suspense 模式下的状态收敛逻辑能让无限加载列表在类型层面做到零undefined判断、零冗余标志位。类型别名的定义与在仓库中的位置在仓库文档 UseSuspenseInfiniteQueryResult.md 中该类型被精确表述为type UseSuspenseInfiniteQueryResultTData, TError OmitKeyofDefinedInfiniteQueryObserverResultTData, TError, isPlaceholderData;它的真实定义位于 packages/preact-query/src/types.ts#L388-L394是一条仅两行的类型工具export type UseSuspenseInfiniteQueryResult TData unknown, TError DefaultError, OmitKeyof DefinedInfiniteQueryObserverResultTData, TError, isPlaceholderData 其语义来自源码 doc 注释它是useSuspenseInfiniteQuery的返回值类型。与DefinedUseInfiniteQueryResult完全一致唯独少了isPlaceholderData——因为 Suspense 钩子永远不会渲染占位数据placeholder data。从结构看这条类型别名只做两件事引用 core 中确定的无限查询结果DefinedInfiniteQueryObserverResult通过工具类型OmitKeyof剥离其中恒为false的死字段isPlaceholderData。与兄弟类型的关系DefinedUseInfiniteQueryResult 与 UseInfiniteQueryResult对比同目录下另外两个类型别名可以更清晰地定位它的差异类型别名底层来源data 是否可能为 undefined是否有 isPlaceholderData对应 HookUseInfiniteQueryResultInfiniteQueryObserverResult是pending 阶段为undefined有useInfiniteQuery未设initialDataDefinedUseInfiniteQueryResultDefinedInfiniteQueryObserverResult否始终定义有恒为 falseuseInfiniteQuery设置initialDataUseSuspenseInfiniteQueryResultOmitKeyofDefinedInfiniteQueryObserverResult, isPlaceholderData否始终定义已移除useSuspenseInfiniteQuery其中 DefinedUseInfiniteQueryResult 的定义就在 types.ts#L376-L379它只是对 core 类型的直出re-exportexport type DefinedUseInfiniteQueryResult TData unknown, TError DefaultError, DefinedInfiniteQueryObserverResultTData, TError也就是说UseSuspenseInfiniteQueryResult与DefinedUseInfiniteQueryResult的数据确定性完全等价差别仅在于前者额外去掉了一个在 Suspense 场景下毫无意义的字段。OmitKeyof 移除 isPlaceholderData 的底层原因OmitKeyof工具类型定义在 core 包 packages/query-core/src/types.ts#L19。它之所以出现在这里是因为DefinedInfiniteQueryObserverResult的各个成员类型中isPlaceholderData恒等于false见下文联合类型因此在类型层面它是一个死字段它是恒定标志位读它永远得到false不会提供任何信息Suspense 语义下组件要么暂停挂起、要么拿到真实或已缓存数据不存在用占位数据先渲染一帧的中间态保留它只会诱导开发者写出result.isPlaceholderData ...这类永不成立的分支。为此useSuspenseInfiniteQuery的实现packages/preact-query/src/useSuspenseInfiniteQuery.ts#L146-L156在把 options 交给useBaseQuery前就显式把placeholderData置为undefinedreturn useBaseQuery( { ...options, enabled: true, suspense: true, throwOnError: defaultThrowOnError, placeholderData: undefined, }, InfiniteQueryObserver as typeof QueryObserver, queryClient, ) as InfiniteQueryObserverSuccessResultTData, TError注意最末的断言类型是InfiniteQueryObserverSuccessResult成功结果配合上层的类型别名一起从运行时与编译期两侧共同保证了返回的一定是确定数据。类型工具的使用提示由于OmitKeyof只删键、不动联合成员配合DefinedInfiniteQueryObserverResult这类联合类型使用时isPlaceholderData会被从每一个联合分支上剥除最终得到的仍是一个干净的联合——这正是 preact 层希望对外呈现的精简结果类型。这与 React Query 中UseSuspenseQueryResult对DefinedQueryObserverResult做DistributiveOmit的思路见 types.ts#L336-L342如出一辙。底层形态DefinedInfiniteQueryObserverResult 联合的构成DefinedInfiniteQueryObserverResult定义在 packages/query-core/src/types.ts#L1051-L1056是两个分支的联合export type DefinedInfiniteQueryObserverResult TData unknown, TError DefaultError, | InfiniteQueryObserverRefetchErrorResultTData, TError | InfiniteQueryObserverSuccessResultTData, TError这两个分支意味着一旦进入了确定数据态结果只可能是两种情形InfiniteQueryObserverSuccessResulttypes.ts#L1015-L1031data有值、error: null、status: success、isSuccess: true且isPlaceholderData: falseInfiniteQueryObserverRefetchErrorResulttypes.ts#L999-L1013后台刷新失败但因为有已缓存的data可继续展示所以data仍然有值error携带错误、status: error、isRefetchError: true。对比之下普通非 SuspenseInfiniteQueryObserverResulttypes.ts#L1058-L1066还要并入LoadingResult、PendingResult、LoadingErrorResult与PlaceholderResult其中data是undefined的分支占据多数——这也是普通useInfiniteQuery必须处理isPending而useSuspenseInfiniteQuery不需要的根本原因。可以推断对UseSuspenseInfiniteQueryResultTData, TError的使用者来说status的实际取值域收敛为error | success派生的isSuccess/isRefetchError/isFetchNextPageError/isFetchPreviousPageError等标志位随之变得有明确含义这是类型系统对 Suspense 控制流出错抛给 Error Boundary成功则渲染的直接投影。类型参数详解TData 与 TError与文档一致的默认值与含义如下类型参数默认值含义TDataunknownselect执行完成后data最终呈现的类型。无限查询中它默认是InfiniteDataTQueryFnData由选项层的默认值决定若传入了select变换函数则TData应描述变换后的结构而queryFn的单页结果仍用独立的类型参数承载。TErrorDefaultErrorqueryFn可能抛出的错误类型。无限查询的每一页由同一个queryFn按pageParam拉取因此所有页面共享同一错误类型。在 types.ts 的选项接口 UseSuspenseInfiniteQueryOptions 中对应的三个关键上游类型参数为TQueryFnData单页数据的原始返回类型默认unknownTDataselect之后的结果类型默认InfiniteDataTQueryFnData即所有已拉取页面 各页 pageParam的聚合形态TPageParam传给queryFn拉取某一页的分页参数类型默认unknown。InfiniteData结构定义于 packages/query-core/src/types.ts#L210 附近最核心的两个成员是pages: TData[]与pageParams这也是使用data.pages.map(...)渲染无限列表时遍历的对象。实战在组件中消费该结果类型UseSuspenseInfiniteQueryResult通常不会由开发者手写标注——它由useSuspenseInfiniteQuery的返回推断出来但理解它的形状决定了你能安全解构哪些字段。仓库源码中的使用示例见 useSuspenseInfiniteQuery.ts#L51-L80演示了典型消费方式function Projects() { // data 被保证有值——无需 isPending 判断 const { data, fetchNextPage, hasNextPage, isFetching, isFetchingNextPage } useSuspenseInfiniteQuery({ queryKey: [projects], queryFn: ({ pageParam }) fetchProjects(pageParam), initialPageParam: 0, getNextPageParam: (lastPage) lastPage.nextId, }) return ( div ul {data.pages.map((page) page.projects.map((project) li key{project.id}{project.name}/li), )} /ul button onClick{() fetchNextPage()} disabled{!hasNextPage || isFetching} {isFetchingNextPage ? Loading more... : hasNextPage ? Load More : Nothing more to load} /button /div ) }正是因为返回类型是确定性的示例里可以直接读取data.pages而不需要任何空值兜底。至于错误处理首次拉取失败且无缓存数据时useSuspenseInfiniteQuery会通过throwOnError: defaultThrowOnError把错误抛出渲染树见 suspense.ts#L12-L20其判定条件为query.state.data undefined因此外层必须配合QueryErrorResetBoundary与错误边界做重试而后台刷新失败则走isRefetchError分支继续渲染旧数据不会中断页面。字段语义速查在类型层面可安全使用、且与 Suspense 语义吻合的常用字段包括data聚合后的分页数据类型为TData默认InfiniteDataTQueryFnData永不为undefinedstatus收敛为error | successisPending在类型上不存在已被联合排除isPlaceholderData已移除不存在于该类型上编译期报错防止误用fetchNextPage/fetchPreviousPage加载更多/加载上一页的命令式方法hasNextPage/hasPreviousPage、isFetchingNextPage/isFetchingPreviousPage配合按钮开关与加载态isRefetchError后台刷新失败标记。源码注释还提醒了两点边界见 useSuspenseInfiniteQuery.ts#L22-L30多个 Suspense 查询在同组件内会串行挂起、形成请求瀑布命令式的fetchNextPage调用可能与默认重刷行为互相干扰建议只在用户操作回调里调用或配合hasNextPage !isFetching等条件守卫。使用前的注意事项该类型是Preact 专属类型仅从tanstack/preact-query的useSuspenseInfiniteQuery返回React、Vue 等适配层有各自独立的结果类型定义不可混用。组件必须被Suspense包裹错误路径必须由外层错误边界结合QueryErrorResetBoundary兜住否则首次加载失败会冒泡中断渲染。queryFn不允许使用skipToken——Suspense 钩子没有禁用查询的中间态源码会在非生产环境打印skipToken is not allowed for useSuspenseInfiniteQuery的错误提示useSuspenseInfiniteQuery.ts#L140-L144。延伸阅读Hook 声明useSuspenseInfiniteQuery.md类型定义源文件packages/preact-query/src/types.tscore 层无限查询结果类型packages/query-core/src/types.ts#L946-L1066无限查询使用指南infinite-queries.md兄弟类型DefinedUseInfiniteQueryResult、UseInfiniteQueryResult、UseSuspenseQueryResult【免费下载链接】query Powerful asynchronous state management, server-state utilities and data fetching for the web. TS/JS, React Query, Solid Query, Svelte Query and Vue Query.项目地址: https://gitcode.com/GitHub_Trending/qu/query创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表