HuolalaTech / react-query-kit

🕊️ A toolkit for ReactQuery that make ReactQuery hooks reusable and typesafe
MIT License
337 stars 11 forks source link

How to pass any data from middleware to mutationFn? #46

Closed denisborovikov closed 6 months ago

denisborovikov commented 7 months ago

I'm trying to pass data from my middleware to the mutationFn. The only argument mutationFn has is variables but I don't see variables exist in mutationMiddleware options.

const mutationMiddleware: Middleware<MutationHook> = (useMutationNext) => {
  return (options) => {
    const variables = { foo: 'bar' }
    return useMutationNext({ ...options, variables }) // TS2353: Object literal may only specify known properties, and variables does not exist in type
  }
}

const useAddTodo = createMutation({
  mutationFn: async (variables) => {
    return new Promise((resolve) => {
      setTimeout(resolve, 1000)
    })
  },
  use: [mutationMiddleware],
})

Anyway even if I suppress the ts error, the variables from the middleware are overriden with variables from the mutate:

const todo = useAddTodo()

todo.mutate('hello') // this is what `mutationFn` gets. { foo: 'bar' } is dropped.
liaoliao666 commented 7 months ago

Using option onMutate and mutationFn’s context.

Sorry Now I'm on vacation in Thailand without my Mac. So I can not show u the code quickly.

denisborovikov commented 7 months ago

Sure thing, thanks! Enjoy the vacation!

denisborovikov commented 7 months ago

For the later discussion - I refreshed my memory and checked the docs. The mutationFn doesn't receive any other arguments than variables. The context returned from the onMutate is supposed to be used for the optimistic updates and passed down to other callbacks (onSuccess, etc.) but not to the mutation function.

liaoliao666 commented 7 months ago

I forgot it. Or You can pass a new mutationFn that warped the original mutationFn. For example

const mutationMiddleware: Middleware<MutationHook> = (useMutationNext) => {
  return (options) => {
    const mutationFn = (variables) => {
       const mergedVariables = { foo: 'bar', ...variables}
       return options.mutationFn(mergedVariables)
    }
    return useMutationNext({ ...options, mutationFn }) 
  }
}
denisborovikov commented 7 months ago

Aw right, thank you for the insight! I'll give it a try.