graphql-code-generator-community
graphql-code-generator-community copied to clipboard
typescript-react-query uses deprecated (v3.x) `useQuery` arguments
Is your feature request related to a problem? Please describe.
typescript-react-query generates query hooks that call useQuery using the old v3.x syntax of useQuery(queryKey, queryFn, options), which is deprecated and support will be removed in v5.
While this syntax still works in @tanstack/react-query v4.x, the official v4.x syntax (and v5.x beta) is to just pass one object, useQuery(options), which can contain queryKey and queryFn as properties.
The main practical impact of this are:
- v5.x (currently in beta) will remove support for this syntax, so generated hooks will not be compatible with v5
- It causes a limitation where it is not currently possible to pass a custom fetcher function to a generated hook. Calling
useSomeGeneratedQuery(variables, { queryFn: somefn })doesn't work as expected.someFnis never used (presumably because in the old v.3.x syntax,queryFnwasn't a supported option, it was passed as the second argument which is hardcoded in generated hooks).
Describe the solution you'd like
An option to generate useQuery hooks that use the >=4.x syntax. They'd probably look like this:
export const useSomeDataQuery = <TData = SomeDataQuery, TError = unknown>(
variables?: SomeDataVariables,
options?: UseQueryOptions<SomeDataQuery, TError, TData>
) =>
useQuery<UseQueryOptions<SomeDataQuery, TError, TData>>({
queryKey: variables === undefined ? ['SomeData'] : ['SomeData', variables],
queryFn: fetchData<SomeDataQuery, SomeDataQueryVariables>(SomeDataDocument, variables)
...options // spread last so, unlike in the current implementation, options.queryFn will be applied and used
})
That should be compatible with v5.x, match the docs for v4.x, and enable usage like this (which isn't currently possible):
const { data, isLoading, ...etc } = useSomeDataQuery(variables, {
// with the current syntax, this is supposedly a valid option but doesn't do anything
queryFn: someDifferentFnForThisCase
})
Describe alternatives you've considered
This could also be the default behaviour since it's the documented syntax for v4.x but that might be a breaking change so it's probably best to make it an opt-in option, then become the default in this package's v5.x release?
As a temporary work around for the lack of queryFn option support, I'm doing something like this:
In codegen.ts config:
export default {
// ...
generates: {
// ...
config: {
// ...
exposeFetcher: true,
exposeQueryKeys: true
}
}
}
In the hook that uses the query:
import { useSomeDataQuery, type SomeDataQuery } from './useGeneratedGraphqlHooks'
import { useQuery } from '@tanstack/react-query'
const transformSomeData = (data: SomeDataQuery) => {
// custom query function logic here
}
const queryKey = useSomeDataQuery.getKey() // generated if `exposeQueryKeys: true` in config
const fetcher = useSomeDataQuery.fetcher() // generated if `exposeFetcher: true` in config
const queryFn = () => fetcher().then(transformSomeData)
const useSomeData = () => {
// This will benefit from typescript signatures etc based on `SomeData` codegen content
const { data, isLoading, ...etc } = useQuery({ queryKey, queryFn, ...moreOptions })
// ...
Although it doesn't allow a fetcher option override with v4, this PR adds support for react-query v5 with the updated object format
codegen.ts now supports:
config: {
reactQueryVersion: 5
}