-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Changed return type of useMutation when ignoreResult is explicitly set to true to hide unset result #12277
Conversation
🦋 Changeset detectedLatest commit: 185c889 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
👷 Deploy request for apollo-client-docs pending review.Visit the deploys page to approve it
|
✅ Docs preview readyThe preview is ready to be viewed. View the preview File Changes 0 new, 2 changed, 0 removed
Build ID: a6b98535a5473ca491c3f8c8 URL: https://www.apollographql.com/docs/deploy-preview/a6b98535a5473ca491c3f8c8 |
…t to true to hide unset result
ef8b036
to
ac38202
Compare
Hey @Cellule 👋 These are on my TODO list to review tomorrow (Friday). Just wanted you to know I saw these come in and will get to these very soon! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change is great and I do agree it should help prevent some crashes due to the types being wrong.
I had one minor change for accessing fields that are there at runtime even with ignoreResults: true
. Once that is updated, I'd be happy to get this into the next release. Thanks for the contribution!
): [ | ||
MutationFunction<TData, TVariables, TContext, TCache>, | ||
// result is not reliable when ignoreResults is true | ||
Pick<MutationResult<TData>, "reset">, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like we still return loading
, called
, and client
properties even when ignoreResults
are set. They just happen to use their initial values:
apollo-client/src/react/hooks/useMutation.ts
Lines 88 to 92 in eeb5f3c
const [result, setResult] = React.useState<Omit<MutationResult, "reset">>({ | |
called: false, | |
loading: false, | |
client, | |
}); |
Can we include those properties here as well? I see no reason not to be able to access them, even if loading
or called
never changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The biggest problem I've seen is that while the properties are there at runtime, their value is always unset.
Trying to use them is almost sure to be a bug.
In my opinion, I feel that at runtime the unreliable fields should not be returned, but that would be breaking change and I wasn't keen on going down that route.
Even changing the type has the potential to cause typescript errors after update, but it should in theory find potential bugs in the code.
I see that client
is potentially correct IF not provided when calling the mutation
Now that I review it a bit more, I now notice that in the catch
case it'll actually set the result to have an error
But if the mutation is called another time and succeeds, the error won't be cleared in the result making it even more unreliable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We've got a planning meeting tomorrow so let me take this to the team and get their thoughts on this.
// TODO This FetchResult<TData> seems strange here, as opposed to an | ||
// ApolloQueryResult<TData> | ||
) => Promise<FetchResult<MaybeMasked<TData>>>, | ||
mutate: MutationFunction<TData, TVariables, TContext, TCache>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💯 I have no idea why this wasn't that way to begin with. Good find!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hahah yeah, I went down the route of making a new type... only to realize it already existed 😅
expectTypeOf(result).toMatchTypeOf<{ reset: () => void }>(); | ||
expectTypeOf(result).not.toMatchTypeOf<MutationResult<Mutation>>(); | ||
expectTypeOf(mutate()).toMatchTypeOf<Promise<FetchResult<Mutation>>>(); | ||
const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you update this to check client
and called
as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, I rewrote it a bit, the destructuring was not needed and made the test longer than needed
@Cellule we met as a team and discussed this change a bit more. The more we talked, the more we questioned why
What we'd like to do instead is deprecate this option and remove it in v4. Would you be willing to update this PR to mark this field as |
I'm all up for that! |
actually, I'll just close this PR and open a new one since there's really nothing shared between the 2 |
We've encountered numerous bugs around this where the default (somehow) was to set
ignoreResult: true
when callinguseMutation
Then devs would try to use
data
orloading
from the tuple without realizing it would never be set.I've been using this patch for a while and it does help avoid bugs