Using component state values in useMutation.mutate (closure/race condition help)
Can someone help me understand why my payload is always an empty string in the code below?
I have a state variable that holds a user's comment which works fine.
When a button is pressed I call useMutation.mutate() and then reset the comment state. Inside the mutationFn the value of comment is always the reset state and it seems like the setState function executes before the mutationFn even if it's called afterward.
I know I can fix this by passing an argument to the mutationFn or resetting the state as part of an onSuccess callback. I know there's better practices than the code below. But what I really want is some help understanding why the comment is the reset value. Why does the mutation seem to execute after the state is updated?
3 Replies
absent-sapphire•9mo ago
Pass it to
mutate and clear it in onSuccess.
Then the click becomes:
Mutate isn't awaitable so what's likely happening is you end up scheduling both the mutate and the state update at the same time. Dominik goes into detail about stuff like this in his blog.
https://tkdodo.eu/blog/breaking-react-querys-api-on-purposeBreaking React Query's API on purpose
Why good API design matters, even if it means breaking existing APIs in the face of resistance.
absent-sapphire•9mo ago
Technically you could await
mutateAsync but I think the callback approach is more common.
I'm a believer that your mutation should have everything given to it, i.e. pass comment to the mutation, not have it reach out for anything. Doing so also allows the devtools to keep track of your mutation payloads. Otherwise it can't know what your request consisted offoreign-sapphireOP•8mo ago
Thank you! These comments helped me get to the bottom of things!