dev-resources.site
for different kinds of informations.
useLazyQuery for @tanstack/react-query
Published at
5/22/2023
Categories
react
graphql
tanstack
Author
kiranmantha
Author
11 person written this
kiranmantha
open
As we all know apollo-graphwl client provide an awesome useLazyQuery
hook to make queries on demand. But the same is not true for react-query by tanstack. There's also few discussion threads in here and here
i created a custom useLazyQuery hook based on the ideas of above threads and this is the result:
// useLazyQuery.ts
import { GraphQLClient } from 'graphql-request';
import { QueryKey, UseQueryOptions, UseQueryResult, useQuery } from '@tanstack/react-query';
import { useState } from 'react';
interface QueryOptions<TInput, TQueryFnData, TResponse>
extends Omit<UseQueryOptions<TQueryFnData, unknown, TResponse, QueryKey>, 'onSuccess' | 'onError'> {
onSuccess?: (data: TResponse, input?: TInput) => void;
onError?: () => void;
}
const extractNameFromQuery = (query: string) => {
const keywordIndex =
query.indexOf(QueryType.QUERY) !== -1
? query.indexOf(QueryType.QUERY) + QueryType.QUERY.length
: query.indexOf(QueryType.MUTATION) + QueryType.MUTATION.length;
return query.substring(keywordIndex, query.indexOf('(')).replace(/ /g, '');
};
const getGraphQLClient = (
_queryName: string,
optionalHeader?: Record<string, string | number | boolean>
): GraphQLClient => {
return new GraphQLClient(env.REACT_APP_API_URL, {
headers: { } as Record<string, string>
});
};
const GQLInteraction = async <T,>(
schema: string,
variables?: Record<string, string[] | number | number[] | unknown> | undefined,
): Promise<T> => {
try {
const queryDescription = extractNameFromQuery(schema);
const client = getGraphQLClient(queryDescription, { ...optionalHeader });
return await client.request(schema, variables);
} catch (err) {
console.log('error', err);
throw err;
}
};
export function useLazyQuery<TInput extends Record<string, unknown>, TQueryFnData, TResponse = TQueryFnData>(
queryName: string,
query: string,
options: QueryOptions<TInput, TQueryFnData, TResponse> = {}
): [(input: TInput) => void, UseQueryResult<TResponse, unknown>] {
const [variables, setVariables] = useState<TInput>();
const queryOptions = {
refetchOnWindowFocus: false,
retry: 0,
enabled: Boolean(variables),
select: data => {
let returnValue: unknown = data;
if (options.select) {
returnValue = options.select(data);
}
return returnValue as never as TResponse;
},
onSuccess: (data: TResponse) => {
options.onSuccess?.(data, variables);
setVariables(undefined);
},
onError: () => {
options.onError?.();
setVariables(undefined);
}
};
const queryInfo = useQuery<TQueryFnData, unknown, TResponse, QueryKey>(
[queryName, variables],
() => GQLInteraction(query, variables),
queryOptions
);
return [setVariables, queryInfo];
}
And this is how i'm using it:
// queries.ts
const getPersonDetail = `query person(id: $id) {
getPersonDetail(id: $id) {
id
name
}
}`;
interface Person {
id: number;
name: string
}
interface PersonResponse {
getPersonDetails: Person;
}
export const useGetPersonDetails = (onSuccess: (person: Person) => void, onError?: () => void) => {
const options = {
onSuccess: (data: PersonResponse, input?: { personId: number }) => {
onSuccess(data.getPersonDetails);
},
onError: () => {
onError?.();
},
};
return useLazyQuery<{ personId: number }, PersonResponse>(
"getPersonDetail",
getPersonDetail,
options
);
};
sometimes we may need to access api payload in success method. in that case, in options.onSuccess
that details can be accessed by the optional 2nd parameter input
as shown above.
That's it for the day.
Don't forget to share your implementation in comments below 👇
Thanks,
Kiran 👋
tanstack Article's
19 articles in total
TanStack Start: The Next.js Alternative for Full-Stack React Development
read article
Let's create Data Table. Part 3: Virtualization
read article
Building a Library to Sync TanStack Table State with URL Parameters
read article
React Toolset for Efficient Code Management
read article
How to reuse queries in Angular Query
read article
Expand Tanstack Table Row to display non-uniform data
read article
TanStack Table Explained: Everything You Need to Know
read article
useSuspenseQuery
read article
Efficiently Managing Remote Data in Vue with Vue Query
read article
How to integrate Gravatar with custom fallback on React App and tanstack query
read article
TANSTACK
read article
How Tanstack improved my React App's performance and user experience.
read article
This is your sign(al) to try TanStack Query & Angular
read article
Creating a Multi-Column Search Feature in a React Data Table
read article
State Management Nx React Native/Expo Apps with TanStack Query and Redux
read article
Using TanStack Query with Next.js
read article
How to Build a Powerful Table in ReactJS with Tanstack and Material UI
read article
useLazyQuery for @tanstack/react-query
currently reading
Create a reusable react-table component with Typescript
read article
Featured ones: