I am using useQuery and useMutation from TanStack Query in my React project.
I use the useMutation hook to update my data and the useQuery hook to fetch it:
In this minimal example, I don't connect to a database as I do in my real project (I'm instead using the useContext here to store the built-up state), but I am still able to reproduce a very similar issue:
When I update my data, the queryCache doesn't seem to remove the query even when I invalidate all queries:
My useUpdateCollections hook:
import axios from 'axios';
import { get, filter } from 'lodash-es';
import { useContext } from 'react';
import { UseMutationResult, useMutation, useQueryClient } from 'react-query';
import { CollectionContext } from '../contexts/collectionContexts';
export default function useMutate() {
const { collections, setCollections } = useContext(CollectionContext);
const queryClient = useQueryClient();
const updateCollectionMutation: UseMutationResult<any> = useMutation({
mutationFn: async (updatedCollection) => {
const nonTargetCollections = filter(collections, (collection) => {
return collection?.name !== updatedCollection?.name;
});
const updatedCollections = [...nonTargetCollections, updatedCollection];
console.log('deleteMe updatedCollections are: ');
console.log(updatedCollections);
const prom = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(setCollections(updatedCollections));
}, 2000);
});
return prom;
},
onSuccess: () => {
console.log('deleteMe onSuccess entered');
const queryCache = queryClient.getQueryCache();
console.log('deleteMe the queryCache is: ');
console.log(queryCache);
const queryKey = ['singleCollection', 'NewHotness'];
let queryState = queryCache.find(queryKey);
if (queryState) {
console.log(`Before Query with key ${queryKey} is in the cache.`);
} else {
console.log(`Before Query with key ${queryKey} is NOT in the cache.`);
}
// queryClient.invalidateQueries({
// queryKey: queryKey,
// });
queryClient.invalidateQueries();
queryState = queryCache.find(queryKey);
if (queryState) {
console.log(`After Query with key ${queryKey} is in the cache.`);
} else {
console.log(`After Query with key ${queryKey} is NOT in the cache.`);
}
},
onError: (error) => {
console.log('deleteMe and error is: ');
console.log(error);
},
});
const mutate = (updatedCollection) =>
updateCollectionMutation.mutateAsync(updatedCollection);
return { updateCollectionMutation, mutate };
}
The output when I update my data:
Before Query with key singleCollection,NewHotness is in the cache.
After Query with key singleCollection,NewHotness is in the cache.
To reproduce the issue:
- Navigate to the stackblitz example.
- Wait for the packages to install.
- You may need to manually type in
/collections
at the end of the project browser URL (circled below): - Click on the "view" icon in the collections page to visit the NewHotness single-collection page.
- Click "Add new video to collection". Type whatever you want in the text input field that appears. Click Add.
- Monitor the developer tools console and hopefully help me understand why the query isn't being invalidated and triggering a re-render.
Many thanks in advance for any help!
If you remove commented code from 37 line 39 line, comment out the code of 40 line, it says, "Before Query with key singleCollection,NewHotness is NOT in the cache. useUpdateCollection.tsx:45 After Query with key singleCollection,NewHotness is NOT in the cache."