Skip to content

Instantly share code, notes, and snippets.

@everdimension
Created July 20, 2022 11:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save everdimension/32dca5b873afaca0b16f79320d0b3190 to your computer and use it in GitHub Desktop.
Save everdimension/32dca5b873afaca0b16f79320d0b3190 to your computer and use it in GitHub Desktop.
A helper on top of useQuery hook
import { useCallback, useState } from 'react';
import { useQuery } from 'react-query';
import type {
QueryKey,
QueryFunction,
UseQueryOptions,
UseQueryResult,
} from 'react-query';
/**
* This is a helper on top of useQuery hook to cover the following case:
*
* We want to use the `keepPreviousData: true` option, but we also want
* to be able to reset cached (previous) data by calling some method.
* The `remove` method returned by useQuery doesn't reset cache when
* `keepPreviousData` is set to `true`. That's why we're adding a helper on top.
*
* This costs us an extra re-render, but achieves desired behavior.
*/
export function useStaleQuery<
TQueryFnData = unknown,
TError = unknown,
TData = TQueryFnData,
>(
queryKey: QueryKey,
queryFn: QueryFunction<TQueryFnData>,
options?: UseQueryOptions<TQueryFnData, TError, TData>,
): UseQueryResult<TData, TError> & { resetStaleData: () => void } {
const [staleableData, setStaleableData] = useState<TData | undefined>(
undefined,
);
const query = useQuery(queryKey, queryFn, {
...options,
keepPreviousData: options?.keepPreviousData ?? true,
onSuccess(data) {
options?.onSuccess?.(data);
setStaleableData(data);
},
});
return {
...query,
data: staleableData,
isLoading:
query.isLoading || (!query.isError && query.isFetching && !staleableData),
resetStaleData: useCallback(() => setStaleableData(undefined), []),
} as UseQueryResult<TData, TError> & { resetStaleData: () => void };
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment