Home > Enterprise >  How to tell React Query fetchQuery to make a new GET request and not used the already cached respons
How to tell React Query fetchQuery to make a new GET request and not used the already cached respons

Time:11-29

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 getSelf = async (): Promise<UserData> =>
    await 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');
        }
    });

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 getSelf() pulls from the cache. How can I instruct fetchQuery to make a fresh GET request and not used the cache?

CodePudding user response:

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.

CodePudding user response:

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');
        }
    });
}
  • Related