React Query
Officialv5.10.4@kubb/plugin-react-query
Infinite queries with useInfiniteQuery
Generate useInfiniteQuery hooks for paginated endpoints, read the next cursor from the response, and stop once the last page arrives.
Generate infinite hooks
When an endpoint pages through results with a query parameter, set infinite next to hooks: true. Only operations that declare infinite.queryParam get an infinite hook, and the hook sends each page param as that parameter:
import { defineConfig } from 'kubb/config'
import { pluginTs } from '@kubb/plugin-ts'
import { pluginFetch } from '@kubb/plugin-fetch'
import { pluginReactQuery } from '@kubb/plugin-react-query'
export default defineConfig({
input: './petStore.yaml',
output: { path: './src/gen' },
plugins: [
pluginTs(),
pluginFetch(),
pluginReactQuery({
hooks: true,
infinite: { queryParam: 'page', initialPageParam: 0, nextParam: 'pagination.next.cursor' },
}),
],
})// src/gen/hooks/useFindPetsByTagsInfinite.ts, types left out
export const findPetsByTagsInfiniteQueryKey = ({ query }: Omit<FindPetsByTagsOptions, 'headers'> = {}) =>
[{ url: '/pet/findByTags', infinite: true }, ...(query ? [query] : [])] as const
export function findPetsByTagsInfiniteQueryOptions({ query }: FindPetsByTagsOptions = {}, config = {}) {
const queryKey = findPetsByTagsInfiniteQueryKey({ query })
return infiniteQueryOptions({
queryKey,
queryFn: async ({ signal, pageParam }) => {
return findPetsByTags({ ...config, query: { ...query, page: pageParam }, signal: config.signal ?? signal, throwOnError: true }).unwrap()
},
initialPageParam: 0,
getNextPageParam: (lastPage) => lastPage?.['pagination']?.['next']?.['cursor'],
})
}import { useFindPetsByTagsInfinite } from './gen/hooks/useFindPetsByTagsInfinite'
const { data, fetchNextPage, hasNextPage } = useFindPetsByTagsInfinite({ query: { tags: ['dog'] } })- Give
initialPageParamthe type of the query parameter. - The infinite key adds
infinite: true, so it never shares a cache entry with the plain query. See TanStack Query keys. - Set
suspense: {}as well to getuseFindPetsByTagsSuspenseInfinite.
Read the next page from the response
The generated getNextPageParam comes from the first of these options you set:
| Option | Generated getNextPageParam |
|---|---|
getNextPageParam | Your function's source, copied as written. It cannot use variables from the config file. |
nextParam | Reads that path on the last page, such as lastPage?.['pagination']?.['next']?.['cursor']. |
cursorParam | Deprecated. Reads that top-level field. |
| None | Counts pages up from initialPageParam until a page is an empty array. |
getPreviousPageParam, previousParam, and cursorParam set the previous page in the same order. With returnType: 'full', the nextParam and cursorParam accessors read from lastPage.data.
hasNextPage never turns false
Generation prints this warning for the operation:
findPetsByTags: the default infinite page params expect an array response and never end for this one. Set `infinite.getNextPageParam` (or `nextParam`) to read the next page from the response.Without getNextPageParam, nextParam, or cursorParam, the hook counts pages up from initialPageParam until a page is an empty array. That works only for array responses, so generation warns for any other response. It skips the warning when previousParam or getPreviousPageParam is set, though the count still never ends.
To fix it, set nextParam to the cursor path, or getNextPageParam when you must compute the next page.
Next, see every infinite option, including definePageParam for a typed getNextPageParam.
