Open
Description
Hi,
Typically we use react-query in the following way, by writing a small reusable hook, ex:
// Example of request vars
type EventRequestVariables {
count: number;
filter: Record<string, string>,
skip: number;
}
// in queries.ts
export const EventsQueries = createQueryKeys('events', {
// bunch of other events related queries
events: (variables: EventRequestVariables) => ({
queryKey: [variables],
queryFn: () => api.events(variables),
}),
})
// in useEvents.ts
export const useEvents = (
variables?: QueryVariables<typeof EventsQueries.events>,
options?: CommonQueryOptions<typeof EventsQueries.events>,
) => {
const { locale } = useLocale();
const { data, status, isLoading, isError, refetch } = useQuery({
...EventsQueries.events({ locale, ...variables }),
staleTime: StaleTime.FOREVER,
...options,
});
return {
data: data?.allPageEvents || [],
status,
isLoading,
isError,
refetch,
};
};
This allows us to easily expose what we need from useQuery while allowing to reuse useEvents
across our application. I've used 2 helper types to extract the variables
and query options
from the QueryKey factory instance.
They could use some love but I think it might be a great addition to this library, also potentially solving issue #40 without making the typings less strict.
// We need to use any here for generics
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type GenericFunction<T = any> = (...args: any[]) => T;
// Extracts the query function
type ExtractQueryFn<T> = T extends GenericFunction<{
queryFn: infer QueryFn;
}>
? QueryFn extends GenericFunction
? QueryFn
: never
: never;
// Extracts the queryData aka the returned Data
type ExtractQueryData<T> = T extends GenericFunction<{
queryFn: infer QueryFn;
}>
? QueryFn extends GenericFunction
? Awaited<ReturnType<QueryFn>>
: never
: never;
// Extract the query key
type ExtractQueryKey<T> = T extends GenericFunction<{
queryKey: infer TQueryKey;
}>
? TQueryKey extends QueryKey
? TQueryKey
: never
: never;
// You can use this to allow passing in custom variables
export type QueryVariables<
T extends GenericFunction,
> = Parameters<T>[0];
// You can use this to pass correct Query options, allowing to pass a custom error
export type CommonQueryOptions<
T extends GenericFunction,
TError = Error,
TQueryData = ExtractQueryData<T>,
TQueryKey extends QueryKey = ExtractQueryKey<T>,
> = UseQueryOptions<TQueryData, TError, TQueryData, TQueryKey>;
Right now it always assumes the Keys are a function, I couldn't really manage to wrap my head around the different options like passing null
or returning a string
WDYT?
Metadata
Metadata
Assignees
Labels
No labels