ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

openapi-react-query 的 useInfiniteQuery 实战指南:基于 OpenAPI 的无限分页查询

openapi-react-query 的 useInfiniteQuery 实战指南:基于 OpenAPI 的无限分页查询 开发工具代码生成后端【免费下载链接】openapi-typescriptGenerate TypeScript types from OpenAPI 3 specs项目地址https://gitcode.com/gh_mirrors/op/openapi-typescript点击查看免费下载导读useInfiniteQuery是openapi-react-query在tanstack/react-query原版useInfiniteQuery之上提供的类型安全封装方法专为加载更多式的无限分页场景设计。本文将讲解如何在生成 OpenAPI 类型的基础上用$api.useInfiniteQuery(...)一键接入游标分页 API并深入其源码实现说明分页游标参数是如何自动注入请求的以及如何通过pageParamName、select等选项定制分页行为。读完本文你将能在项目里用不到 10 行代码实现一个带Load More按钮的完整分页列表。一、useInfiniteQuery 是什么openapi-react-query是一个围绕tanstack/react-query的轻量类型安全封装库配合openapi-fetch发起请求和openapi-typescript根据 OpenAPI 3 schema 生成类型使用让 React 查询代码中的 URL、参数、请求体和响应全部与 schema 严格对齐。useInfiniteQuery是该库提供的五个核心方法之一其余为queryOptions、useQuery、useSuspenseQuery、useMutation见 OpenapiQueryClient 接口定义。它具备以下特点结果与原版一致返回值完全等同tanstack/react-query的useInfiniteQuery结果对象因此data.pages、fetchNextPage、hasNextPage、isFetching等属性都能直接使用查询键固定结构queryKey为[method, path, params]完全类型化data和error均由 OpenAPI schema 自动推导无需手写任何接口类型可透传无限查询选项作为第四个参数传入原版useInfiniteQuery的选项并额外支持pageParamName自定义游标参数名。更完整的库背景、特性清单与安装方式见 openapi-react-query 介绍文档。二、前置准备安装与类型生成在使用useInfiniteQuery之前需要安装本库及两个配套依赖参见 setup 说明npm i openapi-react-query openapi-fetch npm i -D openapi-typescript typescript然后根据你的 OpenAPI 3 schema 生成 TypeScript 类型npx openapi-typescript ./path/to/api/v1.yaml -o ./src/lib/api/v1.d.ts官方文档强烈建议在tsconfig.json中开启noUncheckedIndexedAccess以获得更严格的索引访问类型检查。生成的paths类型将作为后续所有类型推导的根基。三、完整示例加载更多分页列表以下示例来自官方文档由两个文件组成src/api.ts负责创建客户端src/app.tsx使用useInfiniteQuery渲染分页列表。1. 创建 fetch 客户端与 $apisrc/api.tsimport createFetchClient from openapi-fetch; import createClient from openapi-react-query; import type { paths } from ./my-openapi-3-schema; // generated by openapi-typescript const fetchClient createFetchClientpaths({ baseUrl: https://myapi.dev/v1/, }); export const $api createClient(fetchClient);createClient的入参是一个openapi-fetch的FetchClient实例返回带有queryOptions、useQuery、useSuspenseQuery、useInfiniteQuery、useMutation五个方法的类型安全客户端。关于createFetchClient的更多细节可参考 openapi-fetch 文档。2. 在组件中使用 useInfiniteQuerysrc/app.tsximport { $api } from ./api; const PostList () { const { data, fetchNextPage, hasNextPage, isFetching } $api.useInfiniteQuery( get, /posts, { params: { query: { limit: 10, }, }, }, { getNextPageParam: (lastPage) lastPage.nextPage, initialPageParam: 0, } ); return ( div {data?.pages.map((page, i) ( div key{i} {page.items.map((post) ( div key{post.id}{post.title}/div ))} /div ))} {hasNextPage ( button onClick{() fetchNextPage()} disabled{isFetching} {isFetching ? Loading... : Load More} /button )} /div ); }; export const App () { return ( ErrorBoundary fallbackRender{({ error }) Error: ${error.message}} MyComponent / /ErrorBoundary ); };要点解读第三个参数请求选项里的params.query.limit是业务参数会原样发送第四个参数是原版useInfiniteQuery的选项getNextPageParam从最后一页响应中提取下一页游标lastPage.nextPageinitialPageParam指定首页游标0data?.pages按页累积渲染hasNextPage为false时隐藏按钮fetchNextPage拉取下一页isFetching控制按钮禁用与文案。四、分页参数注入原理pageParamName 与游标无限查询与普通查询最大的不同在于分页游标参数不需要你手动写入请求选项。库会自动把它注入到每次请求的 query 参数中。从源码实现看useInfiniteQuery 实现内部queryFn会做如下合并const mergedInit { ...init, signal, params: { ...(init?.params || {}), query: { ...(init?.params as { query?: DefaultParamsOption })?.query, [pageParamName]: pageParam, }, }, };也就是说每次发起请求时保留你传入init中的全部参数如limit: 10将当前页码pageParam写入params.query[pageParamName]pageParamName默认为cursor因此默认发送的游标参数名是?cursorxxx首页pageParam取原版选项initialPageParam的值后续页取getNextPageParam的返回值。如果你服务的分页参数名不是cursor可通过infiniteQueryOptions.pageParamName自定义例如服务端期望follow_cursor$api.useInfiniteQuery( get, /paginated-data, { params: { query: { limit: 3 } } }, { getNextPageParam: (lastPage) lastPage.nextPage, initialPageParam: 0, pageParamName: follow_cursor, // 自定义游标参数名 } );这一点在官方测试中得到了验证测试 should use custom cursor params 断言首屏请求携带follow_cursor0第二页请求携带follow_cursor1。五、API 签名与参数详解官方文档给出的完整调用形态如下const query $api.useInfiniteQuery( method, path, options, infiniteQueryOptions, queryClient );参数说明method必需要使用的 HTTP 方法如get。该值会作为查询键的一部分。参见tanstack/react-query官方文档的 Query Keys 一节。path必需请求的路径名如/posts。必须是你的 schema 中该 method 下真实存在的路径否则会得到类型错误。该值同样作为查询键的一部分。options发起请求所用的 fetch 选项路径/查询参数、请求体等。只有当 OpenAPI schema 要求参数时才是必需的对于无参端点useInfiniteQuery的init参数仍是必填位这与useQuery不同见下文注意事项。options.params会作为查询键的一部分因此不同参数会各自独立缓存。infiniteQueryOptionspageParamName用于分页的查询参数名默认cursor。其余为原版useInfiniteQuery的全部选项如getNextPageParam、initialPageParam、select、staleTime等直接透传给tanstack/react-query。类型上对应源码中的UseInfiniteQueryMethod定义类型声明它在UseInfiniteQueryOptions基础上额外扩展了可选的pageParamName?: string字段。queryClient可选原版queryClient选项用于指定使用哪个 QueryClient 实例。六、源码纵深useInfiniteQuery 的类型与实现结合源码可以更清楚地理解它的行为边界。类型层面UseInfiniteQueryMethod的返回值类型为UseInfiniteQueryResult InferSelectReturnTypeInfiniteDataResponse[data], Options[select], Response[error] 其中Response[data]与Response[error]由FetchResponsePaths[Path][Method], Init, Media推导而来InfiniteData包装后即为{ pages, pageParams }结构。InferSelectReturnType源码会根据select的返回类型动态收敛data的类型——也就是说如果你用select把InfiniteData变换成了别的形状data的类型也会随之精确推导。实现层面核心queryFn在调用openapi-fetch客户端前完成三件事源码方法名大写化后从客户端取出对应方法client[GET]合并signal支持请求取消与init注入pageParam到params.query[pageParamName]。请求若返回error则直接throw error而非返回错误对象这与库内useQuery/useMutation的错误处理策略一致方便配合 ErrorBoundary 或error状态使用data则原样返回以累积到pages中。七、测试验证与进阶用法仓库中的 useInfiniteQuery 测试套件 覆盖了四条关键行为可作为使用参考基本分页正确性首屏请求携带limit3cursor0调用fetchNextPage()后第二页请求携带cursor1data.pages累积两页、hasNextPage为trueselect 变换分页数据利用select反转pages与pageParams适合最新优先的时间线场景测试断言反转后pages与pageParams均按预期排序自定义游标参数名pageParamName: follow_cursor时请求参数变为follow_cursor0/1select 返回类型推导select将InfiniteData拍平为number[]后result.current.data的类型精确收敛为number[] | undefined并以expectTypeOf做了编译期断言。进阶提示首屏与次页响应结构通常首屏响应中应包含nextPage或nextCursor字段配合getNextPageParam: (lastPage) lastPage.nextPage当返回undefined/null时hasNextPage自动变为falseinitialPageParam 必填原版 TanStack Query v5 要求显式提供initialPageParam否则首页游标无从谈起缓存隔离由于queryKey含params不同limit、不同筛选条件的无限查询互不串扰。八、注意事项与边界init参数位置与useQuery不同useInfiniteQuery的init参数在类型签名中是必填位置init: InitWithUnknownsInit即便端点无参也要传占位值这是由方法签名源码决定的分页方式适配pageParamName注入的是query 参数URL 查询字符串如果你的接口采用 offset/limit 数值分页或 Header 分页需要自行在getNextPageParam中换算成游标或改用useQuery 手动请求错误处理请求错误会以异常形式抛出建议像示例那样用 ErrorBoundary 包裹或在组件内捕获依赖版本本库是对tanstack/react-query的薄封装其行为随原版版本演进保持一致请确保项目安装的是与原版接口兼容的版本。通过以上讲解你应该已经能够在实际项目中直接使用$api.useInfiniteQuery快速构建类型安全的无限分页列表并在需要时通过pageParamName与select灵活定制分页语义和数据形态。更多查询相关的封装如queryOptions、useQuery、useSuspenseQuery可继续阅读 openapi-react-query 文档目录 下的对应章节。赞分享开发工具代码生成后端【免费下载链接】openapi-typescriptGenerate TypeScript types from OpenAPI 3 specs项目地址https://gitcode.com/gh_mirrors/op/openapi-typescript点击查看免费下载相关推荐openapi-react-query useQuery 实战指南用完全类型化的 React Query 查询 OpenAPI 接口openapi react query useQuery 实战指南用完全类型化的 React Query 查询 OpenAPI 接口 本文围绕 openapi开发工具代码生成后端Solid Query 无限查询Infinite Queries实战指南用 useInfiniteQuery 实现游标/页码分页与无限滚动Solid Query 无限查询Infinite Queries实战指南用 useInfiniteQuery 实现游标/页码分页与无限滚动 Solid Q前端缓存状态管理TanStack Query Preact 无限查询useInfiniteQuery实战指南分页加载、无限滚动与 maxPages 内存控制TanStack Query Preact 无限查询useInfiniteQuery实战指南分页加载、无限滚动与 maxPages 内存控制 无限列表是前端缓存状态管理上一篇RDP Wrapper Library安全部署如何在企业环境中安全使用并发RDP会话下一篇【免费下载】 Serialib一款简洁高效的跨平台串口通讯库创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表