@tanstack/query-core 5.0.0-alpha.18 → 5.0.0-alpha.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/lib/queryObserver.esm.js +12 -8
- package/build/lib/queryObserver.esm.js.map +1 -1
- package/build/lib/queryObserver.js +12 -8
- package/build/lib/queryObserver.js.map +1 -1
- package/build/lib/queryObserver.mjs +7 -4
- package/build/lib/queryObserver.mjs.map +1 -1
- package/build/umd/index.development.js +7 -4
- package/build/umd/index.development.js.map +1 -1
- package/build/umd/index.production.js +1 -1
- package/build/umd/index.production.js.map +1 -1
- package/package.json +1 -1
- package/src/queryObserver.ts +12 -7
- package/src/tests/queryObserver.test.tsx +55 -0
package/package.json
CHANGED
package/src/queryObserver.ts
CHANGED
|
@@ -64,10 +64,12 @@ export class QueryObserver<
|
|
|
64
64
|
TQueryData,
|
|
65
65
|
TQueryKey
|
|
66
66
|
>
|
|
67
|
-
#previousQueryResult?: QueryObserverResult<TData, TError>
|
|
68
67
|
#selectError: TError | null
|
|
69
68
|
#selectFn?: (data: TQueryData) => TData
|
|
70
69
|
#selectResult?: TData
|
|
70
|
+
// This property keeps track of the last defined query data.
|
|
71
|
+
// It will be used to pass the previous data to the placeholder function between renders.
|
|
72
|
+
#lastDefinedQueryData?: TQueryData
|
|
71
73
|
#staleTimeoutId?: ReturnType<typeof setTimeout>
|
|
72
74
|
#refetchIntervalId?: ReturnType<typeof setInterval>
|
|
73
75
|
#currentRefetchInterval?: number | false
|
|
@@ -414,9 +416,6 @@ export class QueryObserver<
|
|
|
414
416
|
const queryInitialState = queryChange
|
|
415
417
|
? query.state
|
|
416
418
|
: this.#currentQueryInitialState
|
|
417
|
-
const prevQueryResult = queryChange
|
|
418
|
-
? this.#currentResult
|
|
419
|
-
: this.#previousQueryResult
|
|
420
419
|
|
|
421
420
|
const { state } = query
|
|
422
421
|
let { error, errorUpdatedAt, fetchStatus, status } = state
|
|
@@ -490,7 +489,7 @@ export class QueryObserver<
|
|
|
490
489
|
typeof options.placeholderData === 'function'
|
|
491
490
|
? (
|
|
492
491
|
options.placeholderData as unknown as PlaceholderDataFunction<TQueryData>
|
|
493
|
-
)(
|
|
492
|
+
)(this.#lastDefinedQueryData)
|
|
494
493
|
: options.placeholderData
|
|
495
494
|
if (options.select && typeof placeholderData !== 'undefined') {
|
|
496
495
|
try {
|
|
@@ -504,7 +503,11 @@ export class QueryObserver<
|
|
|
504
503
|
|
|
505
504
|
if (typeof placeholderData !== 'undefined') {
|
|
506
505
|
status = 'success'
|
|
507
|
-
data = replaceData(
|
|
506
|
+
data = replaceData(
|
|
507
|
+
prevResult?.data,
|
|
508
|
+
placeholderData as unknown,
|
|
509
|
+
options,
|
|
510
|
+
) as TData
|
|
508
511
|
isPlaceholderData = true
|
|
509
512
|
}
|
|
510
513
|
}
|
|
@@ -568,6 +571,9 @@ export class QueryObserver<
|
|
|
568
571
|
return
|
|
569
572
|
}
|
|
570
573
|
|
|
574
|
+
if (this.#currentResultState.data !== undefined) {
|
|
575
|
+
this.#lastDefinedQueryData = this.#currentResultState.data
|
|
576
|
+
}
|
|
571
577
|
this.#currentResult = nextResult
|
|
572
578
|
|
|
573
579
|
// Determine which callbacks to trigger
|
|
@@ -619,7 +625,6 @@ export class QueryObserver<
|
|
|
619
625
|
| undefined
|
|
620
626
|
this.#currentQuery = query
|
|
621
627
|
this.#currentQueryInitialState = query.state
|
|
622
|
-
this.#previousQueryResult = this.#currentResult
|
|
623
628
|
|
|
624
629
|
if (this.hasListeners()) {
|
|
625
630
|
prevQuery?.removeObserver(this)
|
|
@@ -691,6 +691,61 @@ describe('queryObserver', () => {
|
|
|
691
691
|
expect(observer.getCurrentResult().isPlaceholderData).toBe(false)
|
|
692
692
|
})
|
|
693
693
|
|
|
694
|
+
test('should pass the correct previous data to placeholderData function params when select function is used in conjunction', async () => {
|
|
695
|
+
const results: QueryObserverResult[] = []
|
|
696
|
+
|
|
697
|
+
const key1 = queryKey()
|
|
698
|
+
const key2 = queryKey()
|
|
699
|
+
|
|
700
|
+
const data1 = { value: 'data1' }
|
|
701
|
+
const data2 = { value: 'data2' }
|
|
702
|
+
|
|
703
|
+
const observer = new QueryObserver(queryClient, {
|
|
704
|
+
queryKey: key1,
|
|
705
|
+
queryFn: () => data1,
|
|
706
|
+
placeholderData: (prev) => prev,
|
|
707
|
+
select: (data) => data.value,
|
|
708
|
+
})
|
|
709
|
+
|
|
710
|
+
const unsubscribe = observer.subscribe((result) => {
|
|
711
|
+
results.push(result)
|
|
712
|
+
})
|
|
713
|
+
|
|
714
|
+
await sleep(1)
|
|
715
|
+
|
|
716
|
+
observer.setOptions({
|
|
717
|
+
queryKey: key2,
|
|
718
|
+
queryFn: () => data2,
|
|
719
|
+
placeholderData: (prev) => prev,
|
|
720
|
+
select: (data) => data.value,
|
|
721
|
+
})
|
|
722
|
+
|
|
723
|
+
await sleep(1)
|
|
724
|
+
unsubscribe()
|
|
725
|
+
|
|
726
|
+
expect(results.length).toBe(4)
|
|
727
|
+
expect(results[0]).toMatchObject({
|
|
728
|
+
data: undefined,
|
|
729
|
+
status: 'pending',
|
|
730
|
+
fetchStatus: 'fetching',
|
|
731
|
+
}) // Initial fetch
|
|
732
|
+
expect(results[1]).toMatchObject({
|
|
733
|
+
data: 'data1',
|
|
734
|
+
status: 'success',
|
|
735
|
+
fetchStatus: 'idle',
|
|
736
|
+
}) // Successful fetch
|
|
737
|
+
expect(results[2]).toMatchObject({
|
|
738
|
+
data: 'data1',
|
|
739
|
+
status: 'success',
|
|
740
|
+
fetchStatus: 'fetching',
|
|
741
|
+
}) // Fetch for new key, but using previous data as placeholder
|
|
742
|
+
expect(results[3]).toMatchObject({
|
|
743
|
+
data: 'data2',
|
|
744
|
+
status: 'success',
|
|
745
|
+
fetchStatus: 'idle',
|
|
746
|
+
}) // Successful fetch for new key
|
|
747
|
+
})
|
|
748
|
+
|
|
694
749
|
test('setOptions should notify cache listeners', async () => {
|
|
695
750
|
const key = queryKey()
|
|
696
751
|
|