diff --git a/.changeset/giant-apples-wear.md b/.changeset/giant-apples-wear.md new file mode 100644 index 00000000000..93f7c742aff --- /dev/null +++ b/.changeset/giant-apples-wear.md @@ -0,0 +1,5 @@ +--- +'@tanstack/query-core': patch +--- + +Fix: onMutate callback now runs synchronously when mutationCache.config.onMutate is not defined diff --git a/packages/query-core/src/__tests__/mutationCache.test.tsx b/packages/query-core/src/__tests__/mutationCache.test.tsx index e52498c64f7..50337b0e840 100644 --- a/packages/query-core/src/__tests__/mutationCache.test.tsx +++ b/packages/query-core/src/__tests__/mutationCache.test.tsx @@ -249,6 +249,30 @@ describe('mutationCache', () => { expect(states).toEqual([1, 2, 3, 4]) }) + + test('options.onMutate should run synchronously when mutationCache.config.onMutate is not defined', () => { + const key = queryKey() + const states: Array = [] + + // No onMutate in cache config + const testCache = new MutationCache({}) + const testClient = new QueryClient({ mutationCache: testCache }) + + executeMutation( + testClient, + { + mutationKey: key, + mutationFn: () => sleep(10).then(() => ({ data: 5 })), + onMutate: () => { + states.push('onMutate') + return 'context' + }, + }, + 'vars', + ) + + expect(states).toEqual(['onMutate']) + }) }) describe('find', () => { diff --git a/packages/query-core/src/mutation.ts b/packages/query-core/src/mutation.ts index cf879c1ad33..2483b563366 100644 --- a/packages/query-core/src/mutation.ts +++ b/packages/query-core/src/mutation.ts @@ -212,11 +212,13 @@ export class Mutation< } else { this.#dispatch({ type: 'pending', variables, isPaused }) // Notify cache callback - await this.#mutationCache.config.onMutate?.( - variables, - this as Mutation, - mutationFnContext, - ) + if (this.#mutationCache.config.onMutate) { + await this.#mutationCache.config.onMutate( + variables, + this as Mutation, + mutationFnContext, + ) + } const context = await this.options.onMutate?.( variables, mutationFnContext,