Reputation: 5782
I have the following function that makes a GET request for my user information and caches it using react query's fetchQuery so that every call after the first one does not make a GET request and instead just pulls the data from the cache.
export const getVegetables = async () =>
await queryClient.fetchQuery(['getVegetables'], async () => {
try {
const { data } = await request.get('/vegetables');
return data;
} catch (error) {
throw new Error('Failed to fetch vegetables');
}
});
The problem is that now I actually want to make a new GET request in order to check if the user data has changed, but calling getVegetables()
pulls from the cache. How can I instruct fetchQuery to make a fresh GET request and not used the cache?
Upvotes: 0
Views: 3292
Reputation: 28853
fetchQuery
will always fetch unless there is data in the cache that is considered fresh
. This is determined by the staleTime
setting.
staleTime
defaults to 0
- which means "immediately stale". So the code you are showing that is calling fetchQuery
should always fetch - unless you have a global staleTime
set. You're not showing this in your code, but I guess this must be the reason. Note that fetchQuery
doesn't know about staleTime
being set by other observers (created by useQuery).
Now if you have a globally set staleTime
and that is affecting fetchQuery
, but you still want to always fetch, the best thing you can do is pass staleTime: 0
directly to fetchQuery
. Again, this is the default behaviour, so it's only necessary if you have a global staleTime set:
await queryClient.fetchQuery(
['getSelf'],
async () => { ... },
{ staleTime: 0 }
)
Upvotes: 0
Reputation: 6633
A slight modification to your function will allow you to first invalidate the query (which will remove it from the cache).
export const getSelf = async (skipCache = false) => {
if(skipCache) { queryClient.invalidateQueries(['getSelf']); }
return queryClient.fetchQuery(['getSelf'], async () => {
try {
const { data } = await request.get('/users/me');
// @todo: This sideloads a bunch of stuff, that we could cache
return data;
} catch (error) {
throw new Error('Failed to fetch user information');
}
});
}
Upvotes: 1
Reputation: 652
In case of using fetchQuery, you can set cacheTime to 0 in query options, so every time you call it, it will suggest that cache is outdated and fetch fresh data, but I'd suggest you to use useQuery.
Here you can read about difference between useQuery and fetchQuery
The best way is to use useQuery hook and invalidate that query.
import { useQueryClient } from '@tanstack/react-query'
// Get QueryClient from the context
const queryClient = useQueryClient()
queryClient.invalidateQueries({ queryKey: ['getSelf'] })
After invalidation, it will immediately fetch fresh data.
Upvotes: 1