query: `isFetching` returns wrong value when component is mounted with previously fetched key
Describe the bug
We are using useQuery (with refetchOnMount: false) and the same query key is used for both parent and child components.
The parent has logic where only when isFetching: true the child is rendered.
First render (with key “a”) and first key change (to key “b”) are working as expected, however when we change the key back to previous value (to “a”): for a brief moment the parent gets isFetching: true while child get isFetching: false
Your minimal, reproducible example
https://codesandbox.io/s/is-fetching-bug-hqv1v?file=/src/App.js
Steps to reproduce
On first render the console log looks this way:
parent isFetching=true
child isFetching=true
Starting fetch
parent isFetching=false
First time clicking “Change key” button we get:
parent isFetching=true
child isFetching=true
Starting fetch
parent isFetching=false
Second time clicking “Change key” shows unexpected behavior:
parent isFetching=true
child isFetching=false
Starting fetch
parent isFetching=true
child isFetching=true
parent isFetching=false
Expected behavior
When clicking the “Change key” for the second time, we expect the same result as the first time it was clicked:
parent isFetching=true
child isFetching=true
Starting fetch
parent isFetching=false
However for the parent and child get different values for isFetching
How often does this bug happen?
Every time
Screenshots or Videos
No response
Platform
- Chrome: Version 95
react-query version
v3.34.12
TypeScript version
No response
Additional context
No response
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 1
- Comments: 21
so I don’t really see any way forward with this. It looks like its an edge case that we kinda have to accept for now due to how we set the value of isFetching optimistically.
One workaround I found to make this work consistently is to determine isFetching with
useIsFetchinginstead:here is a sandbox reproduction of your issue, yielding consistent results: https://codesandbox.io/s/is-fetching-bug-forked-ocunx0?file=/src/App.js
note that there are some more re-renders, but this gets better on react 18, which has automatic batching. This sandbox, using react 18 and our v4 beta shows the following output, consistently:
https://codesandbox.io/s/is-fetching-bug-forked-unm5cy?file=/src/App.js
As you can see, there is an additional
parent isFetching=falseoutput at the beginning, which is to be expected, becauseuseIsFetchingdoes not set the fetching state totrueoptimistically - which is what would cause the mentioned problem.I hope this is an acceptable workaround. Closing for now, but feel free to keep the discussion going if you have some new input.
I can reproduce it, even on later versions and with react18, where batching has improved. So it’s not that. Also you can turn
refetchOnMountback on and the issue persists.It’s seems to be a weird case that has to do with the conditional mounting + having cached data available already. I don’t have time to look into this right now, so any help is appreciated
That makes sense. I’ll investigate that.
I was able to reproduce it with such test case:
Now the hard part, to find a bug.