Skip to content

Commit c91c720

Browse files
authored
fix(vue-query): invalidate queries immediately after calling invalidateQueries (#7930)
* fix(vue-query): invalidate queries immediately after call `invalidateQueries` * chore: recovery code comments
1 parent 4977296 commit c91c720

File tree

2 files changed

+74
-15
lines changed

2 files changed

+74
-15
lines changed

packages/vue-query/src/__tests__/queryClient.test.ts

+52-3
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ describe('QueryCache', () => {
188188
})
189189

190190
describe('invalidateQueries', () => {
191-
test('should properly unwrap 2 parameter', async () => {
191+
test('should properly unwrap 2 parameter', () => {
192192
const queryClient = new QueryClient()
193193

194194
queryClient.invalidateQueries(
@@ -198,15 +198,64 @@ describe('QueryCache', () => {
198198
{ cancelRefetch: ref(false) },
199199
)
200200

201-
await flushPromises()
202-
203201
expect(QueryClientOrigin.prototype.invalidateQueries).toBeCalledWith(
204202
{
205203
queryKey: queryKeyUnref,
204+
refetchType: 'none',
206205
},
207206
{ cancelRefetch: false },
208207
)
209208
})
209+
210+
// #7694
211+
test('should call invalidateQueries immediately and refetchQueries after flushPromises', async () => {
212+
const invalidateQueries = vi.spyOn(
213+
QueryClientOrigin.prototype,
214+
'invalidateQueries',
215+
)
216+
const refetchQueries = vi.spyOn(
217+
QueryClientOrigin.prototype,
218+
'refetchQueries',
219+
)
220+
221+
const queryClient = new QueryClient()
222+
223+
queryClient.invalidateQueries({
224+
queryKey: queryKeyRef,
225+
})
226+
227+
expect(invalidateQueries).toBeCalled()
228+
expect(refetchQueries).not.toBeCalled()
229+
230+
await flushPromises()
231+
232+
expect(refetchQueries).toBeCalled()
233+
})
234+
235+
test('should call invalidateQueries immediately and not call refetchQueries', async () => {
236+
const invalidateQueries = vi.spyOn(
237+
QueryClientOrigin.prototype,
238+
'invalidateQueries',
239+
)
240+
const refetchQueries = vi.spyOn(
241+
QueryClientOrigin.prototype,
242+
'refetchQueries',
243+
)
244+
245+
const queryClient = new QueryClient()
246+
247+
queryClient.invalidateQueries({
248+
queryKey: queryKeyRef,
249+
refetchType: 'none',
250+
})
251+
252+
expect(invalidateQueries).toBeCalled()
253+
expect(refetchQueries).not.toBeCalled()
254+
255+
await flushPromises()
256+
257+
expect(refetchQueries).not.toBeCalled()
258+
})
210259
})
211260

212261
describe('refetchQueries', () => {

packages/vue-query/src/queryClient.ts

+22-12
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ref } from 'vue-demi'
1+
import { nextTick, ref } from 'vue-demi'
22
import { QueryClient as QC } from '@tanstack/query-core'
33
import { cloneDeepUnref } from './utils'
44
import { QueryCache } from './queryCache'
@@ -174,17 +174,27 @@ export class QueryClient extends QC {
174174
filters: MaybeRefDeep<InvalidateQueryFilters> = {},
175175
options: MaybeRefDeep<InvalidateOptions> = {},
176176
): Promise<void> {
177-
// eslint-disable-next-line cspell/spellchecker
178-
// (dosipiuk): We need to delay `invalidate` execution to next macro task for all reactive values to be updated.
179-
// This ensures that `context` in `queryFn` while `invalidating` along reactive variable change has correct value.
180-
return new Promise((resolve) => {
181-
setTimeout(async () => {
182-
await super.invalidateQueries(
183-
cloneDeepUnref(filters),
184-
cloneDeepUnref(options),
185-
)
186-
resolve()
187-
}, 0)
177+
const filtersCloned = cloneDeepUnref(filters)
178+
const optionsCloned = cloneDeepUnref(options)
179+
180+
super.invalidateQueries(
181+
{ ...filtersCloned, refetchType: 'none' },
182+
optionsCloned,
183+
)
184+
185+
if (filtersCloned.refetchType === 'none') {
186+
return Promise.resolve()
187+
}
188+
189+
const refetchFilters: RefetchQueryFilters = {
190+
...filtersCloned,
191+
type: filtersCloned.refetchType ?? filtersCloned.type ?? 'active',
192+
}
193+
194+
// (dosipiuk): We need to delay `refetchQueries` execution to next macro task for all reactive values to be updated.
195+
// This ensures that `context` in `queryFn` while `invalidating` along reactive variable change has correct
196+
return nextTick().then(() => {
197+
return super.refetchQueries(refetchFilters, optionsCloned)
188198
})
189199
}
190200

0 commit comments

Comments
 (0)