Home > database >  how to use `useQueries` hook (@tanstack/react-query) with graphql-codegen?
how to use `useQueries` hook (@tanstack/react-query) with graphql-codegen?

Time:11-10

I've been using graphql-codegen for several month, it's a great tool.
I've always used it with @tanstack/react-query useQuery & useMutation hooks.

Today, I would like to use it with useQueries (documentation).
To give you more inputs, I'm receiving a dynamic (then undeterministic) list of ids of same type, and I would like to populate them by querying my graphql api. Because of recursive issues, I can't do reconsiliation on server, so I have to do it on client. This is why I need to batch single queries. And this is why I wish I could use useQueries.

It looks like there's no interoperability with graphql-codegen & useQueries.
Do you confirm ?
If so, which pattern would you recommand in order to run multiple queries in parallel ?

Thanks in advance.

My use case here :

import { useQueries } from '@tanstack/react-query';
import { gql } from 'graphql-request';

import { graphQLClient } from '../../graphQLClient';

export const useGetSomeStuff = (ids: string[]) =>
  useQueries({
    queries: ids.map((id) => ({
      queryKey: ['getSomeStuff', id],
      queryFn: async () =>
        graphQLClient.request(
          gql`
            query GetSomeStuff($id: MongoObjectId!) {
              oneStuff(id: $id) {
                ...SomeFragment
              }
            }
          `,
          { id }
        ),
    })),
  });

generates :

export type GetSomeStuffQueryVariables = Exact<{
  id: Scalars['MongoObjectId'];
}>;

export type GetSomeStuffQuery = {
  __typename?: 'Query';
  // ... generated query
};

export const GetSomeStuffDocument = `
    query GetSomeStuff($id: MongoObjectId!) {
  oneStuff(id: $id) {
    ...SomeFragment
  }
}`;
export const useGetSomeStuffQuery = <
  TData = GetSomeStuffQuery,
  TError = unknown
>(
  client: GraphQLClient,
  variables: GetSomeStuffQueryVariables,
  options?: UseQueryOptions<GetSomeStuffQuery, TError, TData>,
  headers?: RequestInit['headers']
) =>
  useQuery<GetSomeStuffQuery, TError, TData>(
    ['GetSomeStuff', variables],
    fetcher<
      GetSomeStuffQuery,
      GetSomeStuffQueryVariables
    >(client, GetSomeStuffDocument, variables, headers),
    options
  );

You can see that generated code still uses useQuery

CodePudding user response:

I am Charly, working on GraphQL Code Generator.

I can confirm that codegen does not support useQueries() for now. Feel free to submit an issue or a PR on the repository: https://github.com/dotansimha/graphql-code-generator-community/issues/new?assignees=&labels=&template=feature-request.md

CodePudding user response:

As a workaround, I use a handmade hook

import { useQueries, UseQueryOptions } from '@tanstack/react-query';
import { GraphQLClient } from 'graphql-request';

import {
  GetOneStuffDocument,
  GetOneStuffQuery,
  GetOneStuffQueryVariables,
  Scalars,
} from '@foo/data-access';

function fetcher<TData, TVariables>(
  client: GraphQLClient,
  query: string,
  variables?: TVariables,
  headers?: RequestInit['headers']
) {
  return async (): Promise<TData> =>
    client.request<TData, TVariables>(query, variables, headers);
}

export const useGetSomeStuffQuery = <
  TData = GetOneStuffQuery,
  TError = unknown
>(
  client: GraphQLClient,
  variables: { ids: Scalars['MongoObjectId'][] },
  options?: UseQueryOptions<GetOneStuffQuery, TError, TData>,
  headers?: RequestInit['headers']
) =>
  useQueries({
    queries: variables.ids.map((id) => ({
      queryKey: ['GetSomeStuff', id],
      queryFn: fetcher<
        GetOneStuffQuery,
        GetOneStuffQueryVariables
      >(client, GetOneStuffDocument, { id }, headers),
      options,
    })),
  });

It seems to work

  • Related