Prefetching data on hover in combination with global loading indicator causes infinite rerenders #8716
-
Greetings, everyone. But then I decided to implement a global loading indicator using the Here's what I have:The prefetch hook I created:const usePrefetch = (fetchData: ({ queryKey }: { queryKey: QueryKey }) => Promise) => {
const queryClient = useQueryClient();
queryClient.setDefaultOptions({
queries: {
refetchOnMount: false,
refetchOnReconnect: false,
refetchOnWindowFocus: false,
refetchIntervalInBackground: false,
},
});
const prefetch = async (queryKey: QueryKey) => {
await queryClient.prefetchQuery({
queryKey,
queryFn: () => fetchData({ queryKey }),
});
};
return prefetch;
}; How I use the hook:const prefetchPost = usePrefetch(fetchPost);
const prefetchComments = usePrefetch(fetchPostComments);
...
onMouseEnter={() => {
prefetchPost(['posts', post.id.toString()]);
prefetchComments(['comments', post.id.toString()]);
}} The global loading indicator:export function LoadingOverlay() {
const isFetching = useIsFetching();
if (!isFetching) return null;
return (
<div className="loading-overlay">
<div className="spinner"></div>
</div>
);
} The Problem:When I hover and the prefetch is being triggered, I get infinite re-renders (or refetches?). How can I fix this issue so that I don’t get stuck in an infinite loop, and the global loading indicator works as expected? Any help would be appreciated. The original repo, deployed app and minimal example on sandbox are below. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 3 replies
-
a) not a good idea as setting default options doesn’t affect already mounted instances and prefetching respects Now in your case:
not sure what’s the point of such an overlay, as it will actively hinder me in clicking the link, but if you want to only have a single prefetch, set |
Beta Was this translation helpful? Give feedback.
a) not a good idea as setting default options doesn’t affect already mounted instances and
b) this is not a matter of refetches, but of “staleTime”
prefetching respects
staleTime
, so every time the prefetching gets triggered, it will fire a request unless it sees fresh data in the cache.staleTime
is zero per default, so it will always trigger a fetch when called.Now in your case:
no…