Query Persistence Confusion
When I persist a query it seems to completely ignore the specific cacheTime and staleTime I set on the hook level - instead it will just abide by the default values I set on the queryClient.
I just want to make sure I'm understanding the nuances here, if someone could confirm that's the case and maybe provide some strategies as to how to deal with the inability to set a cacheTime, staleTime, or other options on the hook level
4 Replies
like-gold•3y ago
I'm not sure I understand the question. What should staleTime or cacheTime do when it comes to persistence?
harsh-harlequin•3y ago
@mattyice78987 not sure if I understand your question, would be nice to have some real example explaining what is happening in your case and what would you expect to happen.
However my guess is that your question could be related to this (in How it works section):
https://tanstack.com/query/latest/docs/react/plugins/persistQueryClient#how-it-works
cacheTime
and staleTime
set in useQuery
hook are defined only on observer level and they don't affect data saved to your localStorage. It's not connected with data at all, that's why you can set different stale times for the same query key in different observers. If you take a look at shape of data persisted to storage (attached image), you will notice that there is nothing about cache time and stale time - you only have absolute timestamp indicating when data was successfully fetched for the last time.
So when data is hydrated from storage on app startup and there is no active observer for specific query (e.g. screen using hook with custom setting you mentioned is not yet mounted), it will use cacheTime
value defined on your QueryClient
, which is 5 minutes by default. So if query dataUpdatedAt + defaultCacheTime < Date.now()
, query will be removed and garbage collected.
Disclaimer: I'm not a maintainer and all I described above is just my understanding of how it all works. There is pretty big chance that I might be wrong, so would be awesome if someone with better understanding could confirm that 😅
wise-whiteOP•3y ago
@emzet @TkDodo 🔮
my criteria as to what queries get dehyrated is as follows:
so if I add persist: true to the vars for a query it gets persisted. Ideally, I want to designate for each specific query how long it will be considered fresh.
I'm simply unable to do this, I only see a difference in how long the query is held in the queryCache for persisted queries when changing the default slateTime
@emzet I noticed this and thank you for your confirmation, but I also know it's possible to set defaults on a per-query basis.
Also in the example you gave, the default cacheTime is 5 minutes, but lets consider cacheTime and staleTime being Infinity. It seems to me like after the queries are hydrated and the staleTime is defined on the hook level in some component, then the query would then behave as the hook designated
harsh-harlequin•3y ago
That code should work properly as long as you follow
{persist}
object shape for second item in query key array
That's right. If some useQuery
hook with its own staleTime
will be mounted/activated after rehydration and this staleTime
+ last update timestamp will be lower than current timestamp, data will be refetched regardless of default staleTime
setting. As I said - staleTime
is defined per observer .
I think you can't define it globally per query key, but only on the observer level. Data persisted in storage only knows about last update timestamp. It doesn't know anything about stale times defined on hooks level. So when your app is hydrated, and you need to use some query in the component, you can set stale time on that useQuery
and it will decide if it should do refetch or not.