Skip to content

Instantly share code, notes, and snippets.

@Svish
Created March 8, 2021 09:47
Show Gist options
  • Save Svish/fded145a756d9cd8fbb54074b0305f68 to your computer and use it in GitHub Desktop.
Save Svish/fded145a756d9cd8fbb54074b0305f68 to your computer and use it in GitHub Desktop.
react-query setup
import { QueryFunction, QueryFunctionContext } from 'react-query';
import qs, { QueryParams } from './queryString';
import transformResponse from './transformResponse';
export type QueryKey = (string | number | undefined | null | QueryParams)[];
export function createDefaultQueryFn(baseUrl: string): QueryFunction<unknown> {
return async ({
queryKey,
}: QueryFunctionContext<Exclude<QueryKey, string>>) => {
if (queryKey.some((x) => x == null))
throw new Error(`Query key cannot include null or undefined`);
const path = queryKey
.map((k) => (typeof k === 'object' ? qs(k) : String(k)))
.join('/');
const res = await fetch(baseUrl + path, {
credentials: 'include',
});
if (!res.ok) {
throw new Error(await res.text());
}
return transformResponse(await res.text());
};
}
import React, { useMemo } from 'react';
import {
QueryClientProvider,
QueryClient,
QueryCache,
MutationCache,
} from 'react-query';
import { ReactQueryDevtools } from 'react-query/devtools';
import { createDefaultQueryFn } from './defaultQueryFn';
interface Props {
baseUrl: string;
children: React.ReactNode;
}
export default function QueryProvider({
baseUrl,
children,
}: Props): React.ReactElement {
const queryClient = useMemo(
() =>
new QueryClient({
queryCache,
mutationCache,
defaultOptions: {
queries: {
cacheTime: 600000, // 10 min
staleTime: 60000, // 1 min
retry: false,
refetchOnWindowFocus: false,
queryFn: createDefaultQueryFn(baseUrl),
},
},
}),
[baseUrl]
);
return (
<QueryClientProvider client={queryClient}>
{children}
<ReactQueryDevtools />
</QueryClientProvider>
);
}
const queryCache = new QueryCache();
const mutationCache = new MutationCache();
import {
useQuery as useQueryWrapped,
UseQueryOptions,
UseQueryResult,
} from 'react-query';
import { QueryKey } from './defaultQueryFn';
/**
* Wraps `useQuery`, only allowing query keys compatible with our
* default query function.
*/
export default function useQuery<
TQueryFnData,
TError = unknown,
TData = TQueryFnData
>(
queryKey: QueryKey,
options?: UseQueryOptions<TQueryFnData, TError, TData>
): UseQueryResult<TData, TError> {
return useQueryWrapped<TQueryFnData, TError, TData>(queryKey, {
...options,
// Disable if query key includes null or undefined
enabled: !queryKey.some((x) => x == null) && options?.enabled !== false,
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment