diff --git a/docs/framework/react/reference/useMutation.md b/docs/framework/react/reference/useMutation.md index 9147c072ef..1d56ae4cd5 100644 --- a/docs/framework/react/reference/useMutation.md +++ b/docs/framework/react/reference/useMutation.md @@ -48,10 +48,11 @@ mutate(variables, { **Parameter1 (Options)** -- `mutationFn: (variables: TVariables) => Promise` +- `mutationFn: (variables: TVariables, meta?: MutationMeta) => Promise` - **Required, but only if no default mutation function has been defined** - A function that performs an asynchronous task and returns a promise. - `variables` is an object that `mutate` will pass to your `mutationFn` + - `meta` is the optional `meta` parameter which is also passed to `useMutation` - `gcTime: number | Infinity` - The time in milliseconds that unused/inactive cache data remains in memory. When a mutation's cache becomes unused or inactive, that cache data will be garbage collected after this duration. When different cache times are specified, the longest one will be used. - If set to `Infinity`, will disable garbage collection diff --git a/packages/query-core/src/__tests__/mutations.test.tsx b/packages/query-core/src/__tests__/mutations.test.tsx index 7921785fc4..ff934e530d 100644 --- a/packages/query-core/src/__tests__/mutations.test.tsx +++ b/packages/query-core/src/__tests__/mutations.test.tsx @@ -51,7 +51,7 @@ describe('mutations', () => { ) expect(fn).toHaveBeenCalledTimes(1) - expect(fn).toHaveBeenCalledWith('vars') + expect(fn).toHaveBeenCalledWith('vars', undefined) }) test('mutation should set correct success states', async () => { @@ -423,6 +423,21 @@ describe('mutations', () => { expect(onSuccess).toHaveBeenCalledWith(2) }) + test('mutationFn should have access to mutation meta', async () => { + const mutation = new MutationObserver(queryClient, { + mutationFn: (_: void, meta) => { + return Promise.resolve(meta?.test) + }, + meta: { + test: 'update', + }, + }) + + await mutation.mutate() + + expect(mutation.getCurrentResult().data).toEqual('update') + }) + describe('scoped mutations', () => { test('mutations in the same scope should run in serial', async () => { const key1 = queryKey() diff --git a/packages/query-core/src/mutation.ts b/packages/query-core/src/mutation.ts index 3aced112e3..b3361ba14a 100644 --- a/packages/query-core/src/mutation.ts +++ b/packages/query-core/src/mutation.ts @@ -171,7 +171,7 @@ export class Mutation< if (!this.options.mutationFn) { return Promise.reject(new Error('No mutationFn found')) } - return this.options.mutationFn(variables) + return this.options.mutationFn(variables, this.options.meta) }, onFail: (failureCount, error) => { this.#dispatch({ type: 'failed', failureCount, error }) diff --git a/packages/query-core/src/types.ts b/packages/query-core/src/types.ts index e4ed081539..412a2262db 100644 --- a/packages/query-core/src/types.ts +++ b/packages/query-core/src/types.ts @@ -1089,6 +1089,7 @@ export type MutationMeta = Register extends { export type MutationFunction = ( variables: TVariables, + meta?: MutationMeta ) => Promise export interface MutationOptions<