dotansimha / graphql-code-generator-community

MIT License
112 stars 142 forks source link

typescript-react-query uses deprecated (v3.x) `useQuery` arguments #389

Open AlanSl opened 1 year ago

AlanSl commented 1 year ago

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:

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?

AlanSl commented 12 months ago

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 })
  // ...
rliljest commented 10 months ago

Although it doesn't allow a fetcher option override with v4, this PR adds support for react-query v5 with the updated object format

ceefour commented 8 months ago

codegen.ts now supports:

config: {
   reactQueryVersion: 5
}