reactjsreact-querytanstackreact-query

React query does not cache query when a key is changed and after that rest to prevoius key


i have a custom hook which uses useQuery from react query internally and i pass an object as params and also pass them object as query key . when i change the object a new request is sent , but when i change the object to a previous state it also send a request again :


const useFetchUsers = options => {
    const { query = {} } = options

    return useQuery({                  
        queryKey: ['users', query],
        queryFn: () => getUsers({ ...query }),
        staleTime: 30 * 1000,
        gcTime: 30 * 1000,
        })   
}

this is the case :

query object is a react state and when i click button information from a form is set as query

at first time the query object is something like this : query = { page : 1 , ...rest }

when the query object changes to this : { page : 2 , ...rest } a new request is sent and it is reasonable

but when i come back to the first page and query object is like the first object above again a new request is sent which is weird i expect that react query to use the cache from previous query .

how can i achieve this ?

update : i tried same code next day and surprisingly it worked and queries cached and i don't know what happened :))).


Solution

  • The behavior you're experiencing is actually expected with React Query

    In this case the JSON.stringy(query) creates a consistent string for identical objects, regardless of their reference, and it will maintain cache correctly for repeated queries with the same parameters.The queryFn still uses the original query object, so the actual API call remains unchanged.

    import { useQuery } from 'react-query';
    
    const useFetchUsers = (options) => {
      const { query = {} } = options;
    
      return useQuery({
        queryKey: ['users', JSON.stringify(query)],
        queryFn: () => getUsers({ ...query }),
        staleTime: 30 * 1000,
        gcTime: 30 * 1000,
      });
    };
    
    export default useFetchUsers;
    

    Remember that this approach assumes that the order of keys in your query object is consistent. If the order might change but represent the same query, you might need a more robust solution, such as sorting the keys before stringifying.