Skip to content
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

fix(regression): avoid calling useQuery onCompleted for cache writes #10229

Conversation

alessbell
Copy link
Member

@alessbell alessbell commented Oct 25, 2022

There are a few related issues pointing to a regression that occurred between v3.4.17 and v3.5.0 and greater: writes to the cache (it doesn't matter how the cache update occurs: directly via cache.writeQuery, via a separate useMutation call, etc.) trigger the onCompleted callback passed to useQuery, whereas in v3.4.x, onCompleted was triggered when the initial network request completed, and not on subsequent cache writes.

My proposed solution here is to compare the previous and current result's loading states: if the loading state doesn't change, onCompleted won't re-fire. This approach has the benefit of working as expected with the notifyOnNetworkStatusChange option which will cause onCompleted to fire after subsequent network requests if notifyOnNetworkStatusChange is set to true.

NB: this change would mean that both direct cache updates to the watched selection set and updates as a result of other network requests (beyond the useQuery hook invocation in question) would never cause onCompleted to fire. This seems more intuitive to me.

refetch and pollInterval

Calls to refetch and queries with pollInterval configured work the same way: they don't update the loading state unless notifyOnNetworkStatusChange is true. If we'd like to preserve the current behavior whereby polling queries fire onChange when watched cache data changes without updating loading/networkStatus, we can keep the condition in b521d12#diff-fb7fa652de6d84c08b87344a06a4d120b664c6e8bf491d16575794c755141477R517. I'm in favor of keeping onCompleted execution consistent across the board, but would love input on this.

There also seems to be some confusion re: polling and onCompleted: looking at this issue, the callback is not repeatedly firing because the cache never changes. #5531

Checklist:

  • If this PR is a new feature, please reference an issue where a consensus about the design was reached (not necessary for small changes)
  • Make sure all of the significant new logic is covered by tests

@alessbell alessbell force-pushed the issue-10076-useQuery-onCompleted-executes-on-cache-writes branch from d903cf4 to e763b92 Compare October 26, 2022 17:47
@alessbell
Copy link
Member Author

Thanks @benjamn! I've added that condition in e763b92. Curiously, while the tests are still passing locally they are now consistently failing on CI... wondering if our CI runners are under heavy load or there's some other reason tests would suddenly start failing (it's even a test added by this PR that is consistently failing now, but was consistently passing before).

@alessbell
Copy link
Member Author

Welp... tests are green now. Ready for a final pass 🙇‍♀️

@alessbell alessbell changed the title fix(regression): avoid calling useQuery onCompleted for cache writes fix(regression): avoid calling useQuery onCompleted for cache writes Oct 26, 2022
@alessbell alessbell changed the base branch from main to release-3.8 October 26, 2022 18:17
Copy link
Member

@benjamn benjamn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @alessbell!

@alessbell alessbell merged commit 250fa53 into release-3.8 Oct 27, 2022
@alessbell alessbell deleted the issue-10076-useQuery-onCompleted-executes-on-cache-writes branch October 27, 2022 18:35
@mogelbrod
Copy link

mogelbrod commented Nov 11, 2022

@alessbell: Given that this PR has been merged into v3.8 - is it correct that the intended behaviour of onCompleted() is to only be called when a request for the associated query has responded with different data than what's in the cache? If that's the case, would it be possible to also expose another callback like onResponse() that gets called whenever a response for a request triggered by the hook is returned, no matter if the data has changed or not? Otherwise there doesn't seem to be any reliable way to react to refetches/polling updates without opting in to having the component also get re-rendered on network status (which can have significant negative performance impact). I'd be happy to open up an issue for this if relevant.

(following up on #5531 (comment))

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 14, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.