Skip to content

Commit 94154d7

Browse files
authored
feat(core): changing mutationKeys should reset observer (#6511)
this allows key-ing of mutations without having to re-mount components using mutations; the mutationKey basically defines the identity of the mutation - it doesn't make much sense to keep data of a different mutationKey around at observer level if the key changes
1 parent e2d5da2 commit 94154d7

File tree

2 files changed

+46
-4
lines changed

2 files changed

+46
-4
lines changed

packages/query-core/src/mutationObserver.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { getDefaultState } from './mutation'
22
import { notifyManager } from './notifyManager'
33
import { Subscribable } from './subscribable'
4-
import { shallowEqualObjects } from './utils'
4+
import { hashKey, shallowEqualObjects } from './utils'
55
import type { QueryClient } from './queryClient'
66
import type {
77
DefaultError,
@@ -53,9 +53,11 @@ export class MutationObserver<
5353
}
5454

5555
setOptions(
56-
options?: MutationObserverOptions<TData, TError, TVariables, TContext>,
56+
options: MutationObserverOptions<TData, TError, TVariables, TContext>,
5757
) {
58-
const prevOptions = this.options
58+
const prevOptions = this.options as
59+
| MutationObserverOptions<TData, TError, TVariables, TContext>
60+
| undefined
5961
this.options = this.#client.defaultMutationOptions(options)
6062
if (!shallowEqualObjects(prevOptions, this.options)) {
6163
this.#client.getMutationCache().notify({
@@ -65,6 +67,14 @@ export class MutationObserver<
6567
})
6668
}
6769
this.#currentMutation?.setOptions(this.options)
70+
71+
if (
72+
prevOptions?.mutationKey &&
73+
this.options.mutationKey &&
74+
hashKey(prevOptions.mutationKey) !== hashKey(this.options.mutationKey)
75+
) {
76+
this.reset()
77+
}
6878
}
6979

7080
protected onUnsubscribe(): void {

packages/query-core/src/tests/mutationObserver.test.tsx

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest'
22
import { waitFor } from '@testing-library/react'
33
import { MutationObserver } from '..'
4-
import { createQueryClient, sleep } from './utils'
4+
import { createQueryClient, queryKey, sleep } from './utils'
55
import type { QueryClient } from '..'
66

77
describe('mutationObserver', () => {
@@ -94,4 +94,36 @@ describe('mutationObserver', () => {
9494

9595
unsubscribe()
9696
})
97+
98+
test('changing mutation keys should reset the observer', async () => {
99+
const key = queryKey()
100+
const mutation = new MutationObserver(queryClient, {
101+
mutationKey: [...key, '1'],
102+
mutationFn: async (text: string) => {
103+
await sleep(5)
104+
return text
105+
},
106+
})
107+
108+
const subscriptionHandler = vi.fn()
109+
110+
const unsubscribe = mutation.subscribe(subscriptionHandler)
111+
112+
await mutation.mutate('input')
113+
114+
expect(mutation.getCurrentResult()).toMatchObject({
115+
status: 'success',
116+
data: 'input',
117+
})
118+
119+
mutation.setOptions({
120+
mutationKey: [...key, '2'],
121+
})
122+
123+
expect(mutation.getCurrentResult()).toMatchObject({
124+
status: 'idle',
125+
})
126+
127+
unsubscribe()
128+
})
97129
})

0 commit comments

Comments
 (0)