Is your feature request related to a problem? Please describe.
I've updated react-query to version 3 which has breaking changes.
MutationConfig and QueryConfig which no longer exist.Describe the solution you'd like
Support react-query version 3.
UseMutationOptions and UseQueryOptions instead.useQuery<TData = unknown, TError = unknown, TQueryFnData = TData> and useMutation<TData = unknown, TError = unknown, TVariables = void, TContext = unknown>Additional context
https://react-query.tanstack.com/guides/migrating-to-react-query-3
https://react-query.tanstack.com/guides/migrating-to-react-query-3#query-data-selectors
My PR addresses the react-query v3 change for the imports.
I haven't taken a look at the generic types yet. I'll try to take a look tomorrow
Ok @zbeyens do you mean something like this?
Modified v3 custom hook
export const useListPostsQueryV3 = <TData>(
variables: ListPostsQueryVariables,
options?: UseQueryOptions<ListPostsQuery, unknown, TData>
) =>
useQuery<ListPostsQuery, unknown, TData>(
["ListPosts", variables],
amplifyFetcher<ListPostsQuery, ListPostsQueryVariables>(
ListPostsDocument,
variables
),
options
);
Example of using the hook
const { data, isLoading, refetch } = useListPostsQueryModified<Post[]>(null, {
refetchOnWindowFocus: false,
select: (posts) => posts.listPosts?.items ?? []
});
This forces the use of a type on the custom useQuery, even when a select is not specified. Unless I'm missing a way to infer the generic type from TData, but I'm not seeing it.
Additionally, should the plugin still support react-query v2 (I made a change to be compatible with both)? Or just force a breaking change?
useQuery<TData = unknown, TError = unknown, TQueryFnData = TData>3 generics:
export const useDocumentItemQueryV3 = <
TData = DocumentItemQuery,
TError = unknown,
TQueryFnData = DocumentItemQuery,
>(
variables: DocumentItemQueryVariables,
options?: UseQueryOptions<TData, TError, TQueryFnData>
) =>
useQuery<TData, TError, TQueryFnData>(
['DocumentItem', variables],
fetcher<TQueryFnData | TData, DocumentItemQueryVariables>(
client,
DocumentItemDocument,
variables
),
options
);
```
I think we can omit the third generic as it should always be `TQueryFnData = DocumentItemQuery`, so with 2 generics:
```typescript
export const useDocumentItemQueryV3 = <
TData = DocumentItemQuery,
TError = unknown,
>(
variables: DocumentItemQueryVariables,
options?: UseQueryOptions<TData, TError, DocumentItemQuery>
) =>
useQuery<TData, TError, DocumentItemQuery>(
['DocumentItem', variables],
fetcher<DocumentItemQuery, DocumentItemQueryVariables>(
client,
DocumentItemDocument,
variables
),
options
);
Example of using the hook:
// data type is DocumentItemQuery['document_by_pk']
const { data } = useDocumentItemQueryV3<DocumentItemQuery['document_by_pk']>(
variables,
{ select: (d) => d.document_by_pk } // new option in v3
)
This forces the use of a type on the custom useQuery, even when a select is not specified. Unless I'm missing a way to infer the generic type from TData, but I'm not seeing it.
This should not be the case for the above solution.
useMutation<TData = unknown, TError = unknown, TVariables = void, TContext = unknown>2 generics, removing variables parameter (see below):
export const useDeleteBlockMutation = <TError = unknown, TContext = unknown>(client: GraphQLClient, options?: UseMutationOptions<DeleteBlockMutation, TError, DeleteBlockMutationVariables, TContext>) =>
useMutation<DeleteBlockMutation, TError, DeleteBlockMutationVariables, TContext>(
fetcher<DeleteBlockMutation, DeleteBlockMutationVariables>(client, DeleteBlockDocument),
options
);
When doing a mutation, you currently have to pass the variables when declaring the hook:
// currently
const { mutate } = useDeleteBlockMutation({ id: 1 }, options);
// should be:
const { mutate } = useDeleteBlockMutation(options);
mutate({ id: 1 });
But it's not the official way react-query is passing variables. It's passed in the mutate function for more control (e.g. called in a callback), which is not supported with the current fetcher.
Can you please use this fetcher for mutations (not compatible with queries):
function mutationFetcher<TData, TVariables>(client: GraphQLClient, query: string) {
return async (variables?: TVariables): Promise<TData> => client.request<TData, TVariables>(query, variables);
}
I would say breaking change. The current version is supporting v2 and does not need to be maintained, so people using react-query 2 can just keep the current version until they upgrade to v3.
@zbeyens Thanks! My generic knowledge is a little lacking. I swear I tried the export const useDocumentItemQueryV3 = <TData = DocumentItemQuery, TError = unknown,>(... example last night and it wasn't working. Fresh day though and it's good to go.
I'll go ahead and rewrite it to drop v2 support. It'll definitely be easier than supporting both.
As for the mutation this appears to work with the current fetch implementations: dropping the variables and calling the function
export const useSubmitRepositoryMutation = (
dataSource: { endpoint: string; fetchParams?: RequestInit },
options?: UseMutationOptions<SubmitRepositoryMutation, unknown, SubmitRepositoryMutationVariables>
) =>
useMutation<SubmitRepositoryMutation, unknown, SubmitRepositoryMutationVariables>(
(variables?: SubmitRepositoryMutationVariables) =>
fetcher<SubmitRepositoryMutation, SubmitRepositoryMutationVariables>(
dataSource.endpoint,
dataSource.fetchParams || {},
SubmitRepositoryDocument,
variables
)(),
options
);
PR has been updated. Let me know what you all think
Perfect! Added a small review
Available in @graphql-codegen/[email protected]. Thank you all!
Most helpful comment
My PR addresses the react-query v3 change for the imports.
I haven't taken a look at the generic types yet. I'll try to take a look tomorrow