-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RTK Query - refetchOnFocus refetches unmounted queries #1530
RTK Query - refetchOnFocus refetches unmounted queries #1530
Comments
Hmm, the questions is really what the best - most correct - behaviour would be. If it's not refetching that data, it might grow stale and not everybody uses The "cleanest" way I see for this would be to just remove that stale data from the store, but that would maybe not be desirable for everyone as well 🤔. Maybe we could make it configurable between
|
I'm used to react-query where it only fetches the mounted queries on refocus. But I see this may not be the best solution because I was actually surprised at the number of queries on refocus. I just spotted it by accident and I think this can happen to others as well, that they don't even know that they may produce a lot of queries by using Having the option between keeping the stale data or refetching it for |
I am also noticing this problem and after reading #1409 it seems like this logic observed here is contradictory to the arguments made in that issue. In that issue, it is mentioned that revalidation only occurs if there are active subscribers to the data. However, here, when focusing, it will refetch ALL endpoints regardless if there are any subscribers. I am using the following options on my API slice (which means ALL queries use this):
I am seeing LOTS of executeQuery actions for endpoints that clearly have no subscribers. Looking in the state before focusing the window, the majority of endpoints have no subscribers. When refocusing, all endpoints are refetched. I am noticing, however, that this might actually be a bug. If I refresh the page, it looks like this: Clearly, the refetchOnFocus option does not check if the subscription is empty, rather it checks if it exists (empty object counts as existing). Is this incorrect behavior? The offending code is here:
This does not check if the subscription sub state is empty, which it should? How about adding a check
|
Any progress on this? This seems like it's a critical bug as it is refetching queries that have no active subscriptions which is really should not. |
Sorry, when you left your last comment I had Covid and I haven't cought up on everything yet. Generally, just "not refetching" doesn't really cut it here, as in that case the data has to be completely removed from the cache, so it is re-queried on a remount. Similar logic to invalidation would apply here. |
@phryneas I opened a PR for the simple change of adding the condition, but if that is not enough I would need some more information to fix it completely. I have not dove too far into the code for RTK Query, but enough to see roughly how it works. However, wouldn't the subscription state become non-empty once you mount your component again, resulting in the if statement not passing and thus refetching the data correctly? |
It would only refetch if Essentially the same as with invalidation goes: if it is mounted, it needs a refetch, if it is not mounted, it needs to be cleaned out so it is fetched on a later mount in the future. redux-toolkit/packages/toolkit/src/query/core/buildMiddleware/invalidationByTags.ts Lines 75 to 82 in d4e95ca
|
@phryneas Isn't this already handled by the redux-toolkit/packages/toolkit/src/query/core/buildMiddleware/cacheCollection.ts Lines 79 to 103 in d5b0eb5
We have 4 cases:
In all these cases, the fix in my PR works as intended; do not refetch if there are no active subscribers. Have I missed something? |
Case 4 is the default case. "serving a cached result" is different from "serving something we know to be out of sync with all other cache results". If you use Thus, that data has to be removed from cache in that case. PS: I'd go as far as saying that the current behaviour of "refetch everything" would be more correct than "refetch everything visible and leave the rest potentially outdated". |
In my use case, I am using If I initiate a query and unmount the component, then blur the window and refocus it, it will re-query all data again for the component that was unmounted (no component is listening on the data). If the reasoning is that However, my question is then, should we ignore |
Yes, it is the same we do for So I guess that the current behaviour might be overfetching a lot, so at this point I'm leaning towards removing it. We could also think about making that configurable and a user choice, but that might be going too far. PS: "data older than PPS: I'm going to bed now, so no more answers from me for today, just so you're not irritated I'm not answering any more ;) |
Yes, of course, I was not referring to it as actually existing, it is removed exactly on time due to the setTimeout. I am beginning to understand exactly what you are saying and I agree, it really does not make sense to know that the cache could include stale data relative to other cache data. I have implemented the same logic from To be exact with my use case, I am calling the query without hooks (as per documentation) and instantly unsubscribing (I only want the data, I do not want to subscribe). This is because I am storing the results in an entity adaptor that I want to manage manually (experimenting with infinite pagination). The problem then arose where it started refetching my data even though I unsubscribed and that was unnecessary (we have real-time long polling that I will integrate into the entity adaptor to keep in sync). Removing the data like I will update my PR with these changes, but first I will also go to bed. |
* Refetch should not happen if no active subscribers Fixes #1530 * Changed logic and added test * Forgot to remove test that should not be merged * Fix return typo and rearranged logic
We're using the
refetchOnFocus
option and setkeepUnusedDataFor
to 5 minutes.The problem is that when the user navigates through the application, this creates a lot of API requests at once when the page is refocused.
This question already seems to have been up for discussion in the old repo:
It would be very useful to change the default behaviour of this (refetch mounted queries only on refocus) or have an option to disable the fetching of unmounted queries.
Changing the default behaviour would be the preferable way IMHO. We don't have the problem of stale data for unmounted queries because we're using the
refetchOnMountOrArgChange
option.The text was updated successfully, but these errors were encountered: