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
isFetching is always true when there's no internet #2361
Describe the bug
When fetching a query offline and using @react-native-community/netinfo as a custom event listener the prop isFetching is always true and the prop status is success even though the request hasn't started yet.
To Reproduce
Just follow the docs here and set up onlineManager with @react-native-community/netinfo
Sorry, I don't find this setting, where can I set the Connection to Local please?
What I have tried is setting the network to offline in the chrome devtools, in which case I see true for isFetching, and react-query does 3 retries. After about 20 seconds, all the retries are done unsuccessfully and the query goes to error state.
Took a look now, but it doesn't start up for me. It hangs in this state forever and doesn't open anything:
Developer tools running on http://localhost:19002
Opening developer tools in the browser...
Not sure where I should type d ? I'm using node 14.16.0. Funnily, the moment it ctrl-c the terminal, the browser tab opens. not really sure what's going on, but isn't there an easier way to reproduce it?
@TkDodod It's just a shortcut, you can open this link http://localhost:19002 directly into your browser. Besides that, make sure to have a USB cable connected to your phone and to allow the dialog Allow USB debugging?
I'm afraid that's the only way I could find to reproduce it :(
make sure to have a USB cable connected to your phone and to allow the dialog Allow USB debugging?
what phone? The instructions didn't mention anything about any phone ... sorry, I'm not playing dumb here but I'd appreciate a really ELI5 step-by-step guide on what to do to get this running. I was thinking this is some sort of emulation that runs in the browser and doesn't require a real phone? I have an iPhone12 fyi
open the browser devtools, turn of your network by emulating offline
go back to the browser and click the button once
--> now a query mounts, and it will stay in loading state forever because we have no internet.
tbh, I'm unsure in what state the query should be. If the query has already loaded once, it will just stay in the state it is in because we are offline, and will continue to fetch if we get online again (refetchOnReconnect).
So by following this through, the query should stay in idle state without data and also with isFetching: false. Does that sound right?
would also ❤️ to hear @tannerlinsley's input on what should generally happen if we try to fetch while being offline, because it might have larger implications, for example:
you are offline and manually invalidateQueries, e.g. with a button click
currently, the fetch also starts even though you are offline, and you will be in isFetching until you get back online. This is pretty much the same scenario as with query mounting.
one option would be to say: we never fetch anything when we are offline, because refetchOnReconnect will likely trigger a fetch anyhow when we come back online...
On Aug 5, 2021, 7:21 AM -0600, Dominik Dorfmeister ***@***.***>, wrote:
would also ❤️ to hear @tannerlinsley's input on what should generally happen if we try to fetch while being offline, because it might have larger implications, for example:
• you are offline and manually invalidateQueries, e.g. with a button click
currently, the fetch also starts even though you are offline, and you will be in isFetching until you get back online. This is pretty much the same scenario as with query mounting.
one option would be to say: we never fetch anything when we are offline, because refetchOnReconnect will likely trigger a fetch anyhow when we come back online...
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or unsubscribe.
I think that’s a safe bet, unless people have fetchers that work offline?
good point. what if you are "fetching" from async storage, or just do Promise.resolve(...). Another argument is that if the backend delivers a cache header (Cache-Control: max-age=60), data will come from the browser cache and it will even work offline (I tested this with the example that goes against the github api), which my proposed change would make impossible. I don't think we can just change that.
The current behaviour is that we start fetching, and then the retrier pauses because we are offline, that's why you're "stuck" in fetching state. There are only three places were we check if we are online:
the retries (mentioned above)
when setting up the focus manager, so refetchOnWindowFocus only works if you are also online.
when setting up the online manager, so refetchOnReconnect only works when you come back online (this one is kinda obvious)
open the browser devtools, turn of your network by emulating offline
go back to the browser and click the button once
--> now a query mounts, and it will stay in loading state forever because we have no internet.
tbh, I'm unsure in what state the query should be. If the query has already loaded once, it will just stay in the state it is in because we are offline, and will continue to fetch if we get online again (refetchOnReconnect).
So by following this through, the query should stay in idle state without data and also with isFetching: false. Does that sound right?
Awesome @TkDodo. Thanks! That's exactly the behavior that I described.
I think that’s a safe bet, unless people have fetchers that work offline?
good point. what if you are "fetching" from async storage, or just do Promise.resolve(...). Another argument is that if the backend delivers a cache header (Cache-Control: max-age=60), data will come from the browser cache and it will even work offline (I tested this with the example that goes against the github api), which my proposed change would make impossible. I don't think we can just change that.
The current behaviour is that we start fetching, and then the retrier pauses because we are offline, that's why you're "stuck" in fetching state. There are only three places were we check if we are online:
the retries (mentioned above)
when setting up the focus manager, so refetchOnWindowFocus only works if you are also online.
when setting up the online manager, so refetchOnReconnect only works when you come back online (this one is kinda obvious)
What if we add a new boolean flag to control this behavior? Something like refetchWhileOffline? Then when this is false, the query would be in idle state
What if we add a new boolean flag to control this behavior? Something like refetchWhileOffline? Then when this is false, the query would be in idle state
thought about this, too, but it would probably still involve some breaking changes. With the current behaviour, we also stop refetching when retrying, and refetchOnWindowFocus does also not refetch if you are offline. This wouldn't go well with a flag that defaults to true, so if we do that, I think this flag should control if being online / offline has any impact at all on your query...
Just want to pitch in and add that this is especially apparent when using React Native and the experimental persistor (AsyncStorage in my case) to create a good caching experience over time.
The loading & error states get persisted. This means that even though network requests aren't in flight, the state indicates that there are. Speaking from experience, there needs to be custom code around loading and error states so they are never persisted simply because network requests don't persist when reloading an app. The web equivalent is to simply refresh the page.
Edit: I added my thoughts in this discussion as I realize it's a bit too big for this particular issue: #2649
I think that’s a safe bet, unless people have fetchers that work offline? Tanner Linsley …
On Aug 5, 2021, 7:21 AM -0600, Dominik Dorfmeister @.***>, wrote: would also ❤️ to hear @tannerlinsley's input on what should generally happen if we try to fetch while being offline, because it might have larger implications, for example: • you are offline and manually invalidateQueries, e.g. with a button click currently, the fetch also starts even though you are offline, and you will be in isFetching until you get back online. This is pretty much the same scenario as with query mounting. one option would be to say: we never fetch anything when we are offline, because refetchOnReconnect will likely trigger a fetch anyhow when we come back online... — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.
Yes, actually people have not offline fetchers 😂
But at least we should handle the error when client's internet is disconnected...
I think there should be a feature to cancel or stop retry: number || true
Activity
TkDodo commentedon Jun 10, 2021
Can you provide a reproduction please? Maybe try to create a codesandbox with react-native-web. There's also https://snack.expo.io/
TkDodo commentedon Jun 26, 2021
Any updates on the reproduction please?
brunohkbx commentedon Jun 28, 2021
@TkDodo sorry for taking so long to answer. I got a little busy last week.
https://snack.expo.io/@bruno.castro/react-query-offline-bug
How to simulate:
isFetchingwill be always trueTkDodo commentedon Jun 28, 2021
Sorry, I don't find this setting, where can I set the Connection to Local please?
What I have tried is setting the network to offline in the chrome devtools, in which case I see
trueforisFetching, and react-query does 3 retries. After about 20 seconds, all the retries are done unsuccessfully and the query goes to error state.brunohkbx commentedon Jun 28, 2021
@TkDodo you need to run it locally.
yarnyarn startdhereLantoLocalSetting the network to offline in the chrome devtools is not enough to simulate this, since the cellphone still has internet.
The following code without internet results in:
It never resolves to error
brunohkbx commentedon Jun 30, 2021
Hey @TkDodo did it work?
TkDodo commentedon Jun 30, 2021
I’m on vacation now, will take a look when I’m back :)
TkDodo commentedon Jul 16, 2021
Took a look now, but it doesn't start up for me. It hangs in this state forever and doesn't open anything:
Not sure where I should type
d? I'm using node 14.16.0. Funnily, the moment it ctrl-c the terminal, the browser tab opens. not really sure what's going on, but isn't there an easier way to reproduce it?brunohkbx commentedon Jul 16, 2021
@TkDodo
dIt's just a shortcut, you can open this linkhttp://localhost:19002directly into your browser. Besides that, make sure to have a USB cable connected to your phone and to allow the dialogAllow USB debugging?I'm afraid that's the only way I could find to reproduce it :(
TkDodo commentedon Jul 16, 2021
I did open localhost manually in the browser.
what phone? The instructions didn't mention anything about any phone ... sorry, I'm not playing dumb here but I'd appreciate a really ELI5 step-by-step guide on what to do to get this running. I was thinking this is some sort of emulation that runs in the browser and doesn't require a real phone? I have an iPhone12 fyi
brunohkbx commentedon Jul 16, 2021
@TkDodo sorry for not being clear enough. Let me try to find a better way to reproduce it
TkDodo commentedon Aug 5, 2021
I think I found a simple reproduction in web:
https://codesandbox.io/s/react-query-always-loading-j85h3?file=/src/App.tsx
steps to reproduce:
--> now a query mounts, and it will stay in loading state forever because we have no internet.
tbh, I'm unsure in what state the query should be. If the query has already loaded once, it will just stay in the state it is in because we are offline, and will continue to fetch if we get online again (
refetchOnReconnect).So by following this through, the query should stay in
idlestate without data and also withisFetching: false. Does that sound right?TkDodo commentedon Aug 5, 2021
would also ❤️ to hear @tannerlinsley's input on what should generally happen if we try to fetch while being offline, because it might have larger implications, for example:
invalidateQueries, e.g. with a button clickcurrently, the fetch also starts even though you are offline, and you will be in
isFetchinguntil you get back online. This is pretty much the same scenario as with query mounting.one option would be to say: we never fetch anything when we are offline, because
refetchOnReconnectwill likely trigger a fetch anyhow when we come back online...tannerlinsley commentedon Aug 5, 2021
TkDodo commentedon Aug 5, 2021
good point. what if you are "fetching" from async storage, or just do
Promise.resolve(...). Another argument is that if the backend delivers a cache header (Cache-Control: max-age=60), data will come from the browser cache and it will even work offline (I tested this with the example that goes against the github api), which my proposed change would make impossible. I don't think we can just change that.The current behaviour is that we start fetching, and then the retrier pauses because we are offline, that's why you're "stuck" in fetching state. There are only three places were we check if we are online:
refetchOnWindowFocusonly works if you are also online.refetchOnReconnectonly works when you come back online (this one is kinda obvious)brunohkbx commentedon Aug 5, 2021
Awesome @TkDodo. Thanks! That's exactly the behavior that I described.
What if we add a new boolean flag to control this behavior? Something like
refetchWhileOffline? Then when this is false, the query would be inidlestateTkDodo commentedon Aug 8, 2021
thought about this, too, but it would probably still involve some breaking changes. With the current behaviour, we also stop refetching when retrying, and
refetchOnWindowFocusdoes also not refetch if you are offline. This wouldn't go well with a flag that defaults totrue, so if we do that, I think this flag should control if being online / offline has any impact at all on your query...scarlac commentedon Sep 8, 2021
Just want to pitch in and add that this is especially apparent when using React Native and the experimental persistor (AsyncStorage in my case) to create a good caching experience over time.
The loading & error states get persisted. This means that even though network requests aren't in flight, the state indicates that there are. Speaking from experience, there needs to be custom code around loading and error states so they are never persisted simply because network requests don't persist when reloading an app. The web equivalent is to simply refresh the page.
Edit: I added my thoughts in this discussion as I realize it's a bit too big for this particular issue: #2649
buglessir commentedon Nov 8, 2021
Yes, actually people have not offline fetchers 😂
But at least we should handle the error when client's internet is disconnected...
I think there should be a feature to cancel or stop
retry: number || truefor example with this config:
TkDodo commentedon Nov 11, 2021
we will be tracking this issue and related ones here from now on:
The plan is to work on this for the next major version, because it will contain breaking changes. Your feedback would be appreciated.