Reputation: 544
Can I use react-query to set cache and stale time based on response from query?
Please see the following code.
import {useQuery} from 'react-query' // v3.39.3
const {data} = useQuery('my-query', () => api.getSomething(), {
cacheTime: data.cacheTime,
staleTime: data.staleTime // <-- I dont think this will work though...
})
Is this possible?
Upvotes: 3
Views: 1020
Reputation: 1
Late to the party, but have you tried something like this?
import { useQuery, useQueryClient } from '@tanstack/react-query';
async function getPlaceholderData() {
await new Promise((r) => void setTimeout(r, Math.random() * 5_000 + 1));
return {
staleTime: Date.now() + Math.random() * 60_000 + 1,
// ...
};
}
function usePlaceholderData() {
const queryClient = useQueryClient();
const queryKey = ['PLACEHOLDER_DATA'];
return useQuery({
queryKey,
queryFn: async () => {
const data = await getPlaceholderData();
queryClient.setQueryDefaults(queryKey, { staleTime:data.staleTime });
return data;
},
});
}
queryClient.setQueryDefaults
will override options you passed to useQuery/useSuspenseQuery. Since it set default options for given query key, you may need to unset
them while invalidating the query.
Upvotes: 0
Reputation: 665
This is possible:
useQuery({
queryKey: ['my-query'],
queryFn: () => api.doSomething();
staleTime: ({ state: { data } }) => data?.staleTime ?? 0
});
From my testing, the function runs whenever the query changes (state, etc) and so this staleTime
function will run before the query runs the first time. Therefore, the data may be undefined, and a default should be returned. 0 means the query will not keep the initialData (if set) for any time, and will immediately run.
Additionally, cacheTime
is now gcTime
to more accurately reflect the purpose of the parameter. I wouldn't expect wanting to change this based on a query, as it relates to garbage collection when queries are unused (meaning how long should the data stay in memory when no component is mounted with useQuery
called using this query). It seems the devs agree, as the field can only be a number or infinity, not a callback like staleTime
.
Reference: Tanstack Query - useQuery docs
Upvotes: 1
Reputation: 17
Yes, you can do it, by using an instance from useQueryClient() with the setQueryData function inside the onSuccess call back function to update cash and stale time, like this:
import {useQuery} from 'react-query' // v3.39.3
const queryClient = useQueryClient();
const {data} = useQuery('my-query', () => api.getSomething(), {
onSuccess: (res) => {
//access to the new cash and stale time from the server response
const {newCashTime,newStaleTime}=res.data
queryClient.setQueryData("my-query", (prevRes) => {
return {
...prevRes,
cacheTime: newCacheTime,
staleTime: newStaleTime,
};
});
},
})
Upvotes: -1