Skip to content

Commit 7d3f7a2

Browse files
authored
fix(query): updating with setQueryData should not affect fetchStatus (#3613)
queries can be fetching _while_ we are making a manual update are still fetching, so we have to set fields that affect the fetch conditionally (fetchStatus, fetchFailureCount)
1 parent e01a7bb commit 7d3f7a2

File tree

4 files changed

+32
-10
lines changed

4 files changed

+32
-10
lines changed

src/core/query.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ interface SuccessAction<TData> {
9898
data: TData | undefined
9999
type: 'success'
100100
dataUpdatedAt?: number
101-
notifySuccess?: boolean
101+
manual?: boolean
102102
}
103103

104104
interface ErrorAction<TError> {
@@ -195,10 +195,7 @@ export class Query<
195195
}
196196
}
197197

198-
setData(
199-
data: TData,
200-
options?: SetDataOptions & { notifySuccess: boolean }
201-
): TData {
198+
setData(data: TData, options?: SetDataOptions & { manual: boolean }): TData {
202199
const prevData = this.state.data
203200

204201
// Use prev data if an isDataEqual function is defined and returns `true`
@@ -214,7 +211,7 @@ export class Query<
214211
data,
215212
type: 'success',
216213
dataUpdatedAt: options?.updatedAt,
217-
notifySuccess: options?.notifySuccess,
214+
manual: options?.manual,
218215
})
219216

220217
return data
@@ -538,10 +535,12 @@ export class Query<
538535
dataUpdateCount: state.dataUpdateCount + 1,
539536
dataUpdatedAt: action.dataUpdatedAt ?? Date.now(),
540537
error: null,
541-
fetchFailureCount: 0,
542538
isInvalidated: false,
543-
fetchStatus: 'idle',
544539
status: 'success',
540+
...(!action.manual && {
541+
fetchStatus: 'idle',
542+
fetchFailureCount: 0,
543+
}),
545544
}
546545
case 'error':
547546
const error = action.error as unknown

src/core/queryClient.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ export class QueryClient {
143143
const defaultedOptions = this.defaultQueryOptions(parsedOptions)
144144
return this.queryCache
145145
.build(this, defaultedOptions)
146-
.setData(data, { ...options, notifySuccess: false })
146+
.setData(data, { ...options, manual: true })
147147
}
148148

149149
setQueriesData<TData>(

src/core/queryObserver.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -650,7 +650,7 @@ export class QueryObserver<
650650
const notifyOptions: NotifyOptions = {}
651651

652652
if (action.type === 'success') {
653-
notifyOptions.onSuccess = action.notifySuccess ?? true
653+
notifyOptions.onSuccess = !action.manual
654654
} else if (action.type === 'error' && !isCancelledError(action.error)) {
655655
notifyOptions.onError = true
656656
}

src/core/tests/queryClient.test.tsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,29 @@ describe('queryClient', () => {
356356

357357
expect(queryCache.find(key)!.state.data).toBe(newData)
358358
})
359+
360+
test('should not set isFetching to false', async () => {
361+
const key = queryKey()
362+
queryClient.prefetchQuery(key, async () => {
363+
await sleep(10)
364+
return 23
365+
})
366+
expect(queryClient.getQueryState(key)).toMatchObject({
367+
data: undefined,
368+
fetchStatus: 'fetching',
369+
})
370+
queryClient.setQueryData(key, 42)
371+
expect(queryClient.getQueryState(key)).toMatchObject({
372+
data: 42,
373+
fetchStatus: 'fetching',
374+
})
375+
await waitFor(() =>
376+
expect(queryClient.getQueryState(key)).toMatchObject({
377+
data: 23,
378+
fetchStatus: 'idle',
379+
})
380+
)
381+
})
359382
})
360383

361384
describe('setQueriesData', () => {

0 commit comments

Comments
 (0)