TanStackT
TanStack3y ago
3 replies
hurt-tomato

Why does invalidateQueries() break mutate()'s onSuccess() sometimes, but not mutateAsync().then() ?

The short gist of the problem is code like this:
// userMutations.js
const useCreateUserMutation = () => {
  const queryClient = useQueryClient()
  return useMutation(resetStudentsProgress, {
    onSuccess: () => queryClient.invalidateQueries(['users', 'list']), // returns a promise to onSuccess
  })
}

// CreateUser.jsx
const createUserMutation = useCreateUserMutation()
const onSubmit = (values) => createUserMutation.mutate(values, {
  onSuccess: () => {
    window.alert('User created successfully') // <- NEVER TRIGGERS
  }
})


I'm intentionally returning the result of invalidateQueries to the
useMutation
options onSuccess as that allows createUserMutation.isLoading to not resolve until both the user is created, AND stale users are succesully re-fetched again. This works fine in 99% of cases.

However, I have a very small number of queries in a very large project that for some reason, hang and only trigger the
useMutation
's config onSuccess, but NOT the mutate() 's provided onSuccess option. I've debugged the issue and noticed interesting things like changing the code to this fixes the subsequent onSuccess:
// userMutations.js
const useCreateUserMutation = () => {
  const queryClient = useQueryClient()
  return useMutation(resetStudentsProgress, {
    onSuccess: () => {
      queryClient.invalidateQueries(['users', 'list']) // No longer returning the promise
    },
  })
}


But this has the problem that createUserMutation.isLoading no longer waits for re-fetching users. I debugged the promise returned by invalidateQueries and it is correctly resolving, so that's not the issue. However, the weirdest thing here is that changing mutate to mutateAsync() DOES work.
const onSubmit = (values) => createUserMutation.mutateAsync(values)
  .then(() => window.alert('User created successfully')) // <- WORKS!!! But why?


This proves invalidateQueries is not hanging. But not why mutate().onSuccess() fails. Help please?
Was this page helpful?