You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Incorrect isFetching state when using the PersistQueryClient #8531
When using the PersistQueryClient on first load, before the data has been hydrated, isFetching is false while isPending true. This may be expected behavior, but seems to contradict the docs which state: "fetching: Is true whenever the queryFn is executing, which includes initial pending as well as background refetches."
In the CodeSandbox I have a dummy restoreClient which just awaits a long setTimeout, and single useQuery. I display the isPending and isFetching variables which are true and false respectively on first load.
Expected behavior
I expect isFetching to be true when isPending is true on first load.
fetching: Is true whenever the queryFn is executing, which includes initial pending as well as background refetches."
It doesn’t contradict the docs. In your reproduction, try adding a console.log into the queryFn. You’ll see that the queryFn is not executing while you are restoring. So the states are correct:
status: 'pending': indicates the query has no data yet, which is correct. we are currently restoring, so the data in the cache is undefined.
fetchStatus: 'idle': The queryFn is not running, so 'idle' is expected.
isFetching and isPending are both derived states from those states.
I’m not sure why you think isFetching should be true when you are clearly not executing the queryFn, or why you think that contradicts the docs. However, if you want to simply know if you are currently restoring - we export a dedicated useIsRestoring() hook that will give you that information.
I misunderstood the docs, I assumed that "includes initial pending as well as background refetches" means that isFetching is true when isPending is true for the first is pending.
I don't think this is how it should work however. It seems counterintuitive that the loading UX would change when a persisting layer is added. As it is currently works if I want to add persisting to an app I will need to go to through all places where I'm using isFetching and also use the useIsRestoring() hook which doesn't seem right.
I don't know what the best change would be for this, and it seems like the worst that can happen with the current behavior is a brief flash of incorrect loading state on first load, so this probably isn't a super important change.
Activity
TkDodo commentedon Jan 19, 2025
It doesn’t contradict the docs. In your reproduction, try adding a
console.loginto thequeryFn. You’ll see that thequeryFnis not executing while you are restoring. So the states are correct:status: 'pending': indicates the query has no data yet, which is correct. we are currently restoring, so the data in the cache isundefined.fetchStatus: 'idle': The queryFn is not running, so'idle'is expected.isFetchingandisPendingare both derived states from those states.I’m not sure why you think
isFetchingshould betruewhen you are clearly not executing thequeryFn, or why you think that contradicts the docs. However, if you want to simply know if you are currently restoring - we export a dedicateduseIsRestoring()hook that will give you that information.JohannesByle commentedon Jan 21, 2025
I misunderstood the docs, I assumed that "includes initial pending as well as background refetches" means that
isFetchingis true whenisPendingis true for the first is pending.I don't think this is how it should work however. It seems counterintuitive that the loading UX would change when a persisting layer is added. As it is currently works if I want to add persisting to an app I will need to go to through all places where I'm using
isFetchingand also use theuseIsRestoring()hook which doesn't seem right.I don't know what the best change would be for this, and it seems like the worst that can happen with the current behavior is a brief flash of incorrect loading state on first load, so this probably isn't a super important change.
TkDodo commentedon Jan 24, 2025
You can check useIsRestoring once at the top of your app and just render nothing until restore is complete.