T
TanStack9mo ago
correct-apricot

unwanted invalidations despite set query key

Hello everyone, I am currently struggeling with understanding why cache invalidations happen. react-query v5.55 Setup: Query Client wrapped around entire App. defaultOptions: staleTime 30min, gcTime: 60min, cacheTime: 60min (for testing), refetchOn Win false, OnMount false, OnReconnect false. cache keys are for simple lists like "artworks", "locations", "contacts". There is no other fluff. Issue: Whenever I use my useCreateObject hook which is supposed to invalidate an exact cache onSuccess and get redirected via useNavigate from react-router-dom, to a specified page, all listed fetch requests on the destination page get invalidated. upon invalidateQueries([key]) all QueryStates get invalidated: true and fetching: true
const useFetch = (key, url) => {
const axiosInstance = useAxios();
return useQuery({
queryKey: [key],
queryFn: async () => {
const response = await axiosInstance.get(url);
return response.data;
},
refetchOnWindowFocus: false,
refetchOnMount: false,
refetchOnReconnect: false,
});
};
const useFetch = (key, url) => {
const axiosInstance = useAxios();
return useQuery({
queryKey: [key],
queryFn: async () => {
const response = await axiosInstance.get(url);
return response.data;
},
refetchOnWindowFocus: false,
refetchOnMount: false,
refetchOnReconnect: false,
});
};
1 Reply
correct-apricot
correct-apricotOP9mo ago
export const useCreateObject2 = (key, url) => {
const axiosInstance = useAxios();
const queryClient = useQueryClient();
const { toast } = useToast();

return useMutation({
mutationFn: async (data) => {
const response = await axiosInstance.post(url, data, {
headers: { "Content-Type": "multipart/form-data" },
});
return response.data;
},
onMutate: async (data) => {
await queryClient.cancelQueries([key]);
const previousData = queryClient.getQueryData([key]);
queryClient.setQueryData([key], (old) => (old ? [data, ...old] : [data]));
return { previousData };
},
onError: (error, variables, context) => {
if (context?.previousData) {
queryClient.setQueryData([key], context.previousData);
}
toast({ title: "Error", description: "Error creating object.", variant: "destructive" });
},
onSuccess: () => {
console.log("ServerrActions - useCreateObject2 - key", key);
queryClient.invalidateQueries([key], { exact: true });

console.log("Artwork query state after invalidation:", queryClient.getQueryState(["artworks"]));
console.log("Statuses query state:", queryClient.getQueryState(["statuses"]));
console.log("Locations query state:", queryClient.getQueryState(["locations"]));
toast({ title: "Create", description: "Object created successfully." });
},
});
};
export const useCreateObject2 = (key, url) => {
const axiosInstance = useAxios();
const queryClient = useQueryClient();
const { toast } = useToast();

return useMutation({
mutationFn: async (data) => {
const response = await axiosInstance.post(url, data, {
headers: { "Content-Type": "multipart/form-data" },
});
return response.data;
},
onMutate: async (data) => {
await queryClient.cancelQueries([key]);
const previousData = queryClient.getQueryData([key]);
queryClient.setQueryData([key], (old) => (old ? [data, ...old] : [data]));
return { previousData };
},
onError: (error, variables, context) => {
if (context?.previousData) {
queryClient.setQueryData([key], context.previousData);
}
toast({ title: "Error", description: "Error creating object.", variant: "destructive" });
},
onSuccess: () => {
console.log("ServerrActions - useCreateObject2 - key", key);
queryClient.invalidateQueries([key], { exact: true });

console.log("Artwork query state after invalidation:", queryClient.getQueryState(["artworks"]));
console.log("Statuses query state:", queryClient.getQueryState(["statuses"]));
console.log("Locations query state:", queryClient.getQueryState(["locations"]));
toast({ title: "Create", description: "Object created successfully." });
},
});
};
How I use the generic ones: export const useFetchArtworks = () => useFetch("artworks", ARTWORKS_LIST_CREATE); export const useCreateArtwork = () => useCreateObject2("artworks", ARTWORKS_LIST_CREATE); const createArtwork = useCreateArtwork(); createArtwork.mutate(data) Side note: Normal routing does not break the cache.

Did you find this page helpful?