React Query
Officialv5.10.4@kubb/plugin-react-query
TanStack Query keys
See the query key each generated React Query hook uses, invalidate or read the cache with it, and add your own prefix to the default key.
The default query key
When you call invalidateQueries, getQueryData, or setQueryData, take the key from the <operation>QueryKey helper in each hook file. It builds [{ url, params }, query, body]:
// src/gen/hooks/useGetPetById.ts
export const getPetByIdQueryKey = ({ path }: Omit<GetPetByIdOptions, 'headers'>) => [{ url: '/pet/:petId', params: path }] as const
// src/gen/hooks/useFindPetsByTags.ts
export const findPetsByTagsQueryKey = ({ query }: Omit<FindPetsByTagsOptions, 'headers'> = {}) =>
[{ url: '/pet/findByTags' }, ...(query ? [query] : [])] as constimport { getPetByIdQueryKey } from './gen/hooks/useGetPetById'
import { findPetsByTagsQueryKey } from './gen/hooks/useFindPetsByTags'
import { queryClient } from './queryClient'
getPetByIdQueryKey({ path: { petId: 1 } }) // [{ url: '/pet/:petId', params: { petId: 1 } }]
findPetsByTagsQueryKey({ query: { tags: ['dog'] } }) // [{ url: '/pet/findByTags' }, { tags: ['dog'] }]
const pet = queryClient.getQueryData(getPetByIdQueryKey({ path: { petId: 1 } }))urlis the spec path with:nameplaceholders, such as'/pet/:petId'.paramsholds the path parameters, when the path has any.queryandbodyfollow when the operation has them and the call passes them.- Headers and cookies stay out of the key.
- Infinite variants add
infinite: trueto the first entry, so they never share a cache entry with the plain query. - Each hook returns the key it used as
queryKeyon its result.
Invalidate every call of an operation
TanStack Query matches a key by its prefix, and an object entry by the fields you pass. A key built without query matches every cached call of that operation with the same path parameters, infinite ones included:
queryClient.invalidateQueries({ queryKey: findPetsByTagsQueryKey() })Mutation keys
Each mutation gets a <operation>MutationKey helper that returns [{ url }], for filters such as useIsMutating or useMutationState:
// src/gen/hooks/useUpdatePet.ts
export const updatePetMutationKey = () => [{ url: '/pet' }] as constimport { useIsMutating } from '@tanstack/react-query'
import { updatePetMutationKey } from './gen/hooks/useUpdatePet'
const saving = useIsMutating({ mutationKey: updatePetMutationKey() })Extend the default key
When you need your own entry, such as an API version, set queryKey and spread queryKeyTransformer. Do not read single entries of its result: they can change between releases.
JSON.stringify(...).import { defineConfig } from 'kubb/config'
import { pluginTs } from '@kubb/plugin-ts'
import { pluginFetch } from '@kubb/plugin-fetch'
import { pluginReactQuery, queryKeyTransformer } from '@kubb/plugin-react-query'
export default defineConfig({
input: './petStore.yaml',
output: { path: './src/gen' },
plugins: [
pluginTs(),
pluginFetch(),
pluginReactQuery({
queryKey: (props) => [JSON.stringify('v2'), ...queryKeyTransformer(props)],
}),
],
})export const getPetByIdQueryKey = ({ path }: Omit<GetPetByIdOptions, 'headers'>) => ["v2", { url: '/pet/:petId', params: path }] as constThe builder also gets the variant, so it can return a different key for suspense or infinite hooks. mutationKey works the same way with mutationKeyTransformer.
Next, generate infinite queries for paginated endpoints.
