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 bug where onCompleted and onError are stale for useMutation. onCompleted and onError could not be changed while a mutation is executing. #9740

Merged

Conversation

charle692
Copy link

fixes #9714
fixes #9493
Related to #9111

Since 3.5.0 there's been a bug with the useMutation hook from this PR that has been preventing us from upgrading to the latest version.

Currently, onCompleted and onError are stale and cannot be updated while a mutation is executing. See here for example on how to reproduce this issue.

The reason for this is that useMutation invokes onCompleted and onError via baseOptions rather than directly from the ref.current. Due to this, it doesn't have the latest copy of the callbacks once the operation is complete.

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

@apollo-cla
Copy link

@charle692: Thank you for submitting a pull request! Before we can merge it, you'll need to sign the Apollo Contributor License Agreement here: https://contribute.apollographql.com/

@@ -710,6 +770,68 @@ describe('useMutation Hook', () => {
expect(onCompleted1).toHaveBeenCalledTimes(1);
expect(onCompleted1).toHaveBeenCalledWith(CREATE_TODO_DATA);
});

it('should allow updating onCompleted while mutation is executing', async () => {
Copy link
Author

Choose a reason for hiding this comment

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

These two specs I added specifically fail without this change, with the change pass. So hopefully this should prevent the issue from being re-introduced.

@brainkim brainkim self-requested a review May 19, 2022 20:57
@brainkim brainkim self-assigned this May 19, 2022
Copy link
Contributor

@brainkim brainkim left a comment

Choose a reason for hiding this comment

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

I took a look at this. I am confirming that the tests fail when using baseOptions (see attached image). @charle692 Thank you so much for tracking down the stale callback issue, writing tests! I’m really sorry that I introduced this bug and I really appreciate you fixing it.
Screen Shot 2022-05-19 at 2 30 37 PM

@brainkim
Copy link
Contributor

@charle692 If you want to rebase this branch against the latest main and delete the .dccache file, I am happy to merge. If you don’t know how to do this I am happy to help or do this for you. Thank you again!

@charle692
Copy link
Author

@charle692 If you want to rebase this branch against the latest main and delete the .dccache file, I am happy to merge. If you don’t know how to do this I am happy to help or do this for you. Thank you again!

Sorry about that, I have a vscode extension that keeps adding that in. I think that you removed it already but I'll double check and remove. At minimum I'll rebase with main to get this up to date.

@charle692
Copy link
Author

charle692 commented May 19, 2022

I took a look at this. I am confirming that the tests fail when using baseOptions (see attached image). @charle692 Thank you so much for tracking down the stale callback issue, writing tests! I’m really sorry that I introduced this bug and I really appreciate you fixing it.

@brainkim no worries at all :) just trying to help out anyway I can! Thanks for taking a look at this so quickly, both of you.

@brainkim brainkim force-pushed the fix_useMutation_onCompleted_stale branch from 9e9f966 to d5d12bf Compare May 23, 2022 17:45
…mpleted and onError could not be changed while a mutation is being executed.

Delete .dccache
@brainkim brainkim force-pushed the fix_useMutation_onCompleted_stale branch from d5d12bf to 343f051 Compare May 23, 2022 17:51
@brainkim
Copy link
Contributor

@benjamn I reverted the changes you made attempting to use the merged options. Firstly, it would be incorrect insofar as the useMutation() hook accepts onError() and onCompleted() callbacks both as an option to the hook call and as an option to the execute function call, for some reason, so if both were defined and you used the merged options you would get potentially surprising behavior where only one gets called. Secondly, the contention right now is that there’s a race condition, so I do think the usage of a React ref is appropriate. If you have concerns, please feel free to modify the code in a separate PR.

@charle692 Thank you again and congratulations on the PR. I really do appreciate the time and effort you put into fixing this.

Unrelatedly, there are batch link tests which are failing 😭

@brainkim brainkim merged commit 47c069b into apollographql:main May 23, 2022
@benjamn
Copy link
Member

benjamn commented May 23, 2022

@charle692 @brainkim These changes are available now if you run npm i @apollo/client@next (to get version 3.6.5, just published to npm). Please let us know if we missed something!

@charle692
Copy link
Author

@benjamn I reverted the changes you made attempting to use the merged options. Firstly, it would be incorrect insofar as the useMutation() hook accepts onError() and onCompleted() callbacks both as an option to the hook call and as an option to the execute function call, for some reason, so if both were defined and you used the merged options you would get potentially surprising behavior where only one gets called. Secondly, the contention right now is that there’s a race condition, so I do think the usage of a React ref is appropriate. If you have concerns, please feel free to modify the code in a separate PR.

@charle692 Thank you again and congratulations on the PR. I really do appreciate the time and effort you put into fixing this.

No worries, after looking at the specs that were failing I can agree with what you are saying. That if we use clientOptions, and onCompleted or onError callbacks are specified by both executeOptions and the original hook only one of them would get called.

Anyways, thanks to both of you for taking a look at this and getting it merged, really appreciate it :).

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 15, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
4 participants