@tanstack/react-query 5.0.0-beta.2 → 5.0.0-beta.20
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/legacy/index.cjs +3 -0
- package/build/legacy/index.cjs.map +1 -1
- package/build/legacy/index.d.cts +3 -2
- package/build/legacy/index.d.ts +3 -2
- package/build/legacy/index.js +2 -0
- package/build/legacy/index.js.map +1 -1
- package/build/legacy/infiniteQueryOptions.cjs.map +1 -1
- package/build/legacy/infiniteQueryOptions.d.cts +1 -1
- package/build/legacy/infiniteQueryOptions.d.ts +1 -1
- package/build/legacy/infiniteQueryOptions.js.map +1 -1
- package/build/legacy/queryOptions.cjs.map +1 -1
- package/build/legacy/queryOptions.d.cts +4 -3
- package/build/legacy/queryOptions.d.ts +4 -3
- package/build/legacy/queryOptions.js.map +1 -1
- package/build/legacy/types.cjs.map +1 -1
- package/build/legacy/types.d.cts +4 -4
- package/build/legacy/types.d.ts +4 -4
- package/build/legacy/useInfiniteQuery.cjs.map +1 -1
- package/build/legacy/useInfiniteQuery.d.cts +2 -1
- package/build/legacy/useInfiniteQuery.d.ts +2 -1
- package/build/legacy/useInfiniteQuery.js.map +1 -1
- package/build/legacy/useQueries.cjs.map +1 -1
- package/build/legacy/useQueries.d.cts +4 -4
- package/build/legacy/useQueries.d.ts +4 -4
- package/build/legacy/useQueries.js.map +1 -1
- package/build/legacy/useQuery.cjs.map +1 -1
- package/build/legacy/useQuery.d.cts +2 -1
- package/build/legacy/useQuery.d.ts +2 -1
- package/build/legacy/useQuery.js.map +1 -1
- package/build/legacy/useSuspenseQueries.cjs +46 -0
- package/build/legacy/useSuspenseQueries.cjs.map +1 -0
- package/build/legacy/useSuspenseQueries.d.cts +66 -0
- package/build/legacy/useSuspenseQueries.d.ts +66 -0
- package/build/legacy/useSuspenseQueries.js +22 -0
- package/build/legacy/useSuspenseQueries.js.map +1 -0
- package/build/legacy/utils.cjs.map +1 -1
- package/build/legacy/utils.d.cts +1 -1
- package/build/legacy/utils.d.ts +1 -1
- package/build/legacy/utils.js.map +1 -1
- package/build/modern/index.cjs +3 -0
- package/build/modern/index.cjs.map +1 -1
- package/build/modern/index.d.cts +3 -2
- package/build/modern/index.d.ts +3 -2
- package/build/modern/index.js +2 -0
- package/build/modern/index.js.map +1 -1
- package/build/modern/infiniteQueryOptions.cjs.map +1 -1
- package/build/modern/infiniteQueryOptions.d.cts +1 -1
- package/build/modern/infiniteQueryOptions.d.ts +1 -1
- package/build/modern/infiniteQueryOptions.js.map +1 -1
- package/build/modern/queryOptions.cjs.map +1 -1
- package/build/modern/queryOptions.d.cts +4 -3
- package/build/modern/queryOptions.d.ts +4 -3
- package/build/modern/queryOptions.js.map +1 -1
- package/build/modern/types.cjs.map +1 -1
- package/build/modern/types.d.cts +4 -4
- package/build/modern/types.d.ts +4 -4
- package/build/modern/useInfiniteQuery.cjs.map +1 -1
- package/build/modern/useInfiniteQuery.d.cts +2 -1
- package/build/modern/useInfiniteQuery.d.ts +2 -1
- package/build/modern/useInfiniteQuery.js.map +1 -1
- package/build/modern/useQueries.cjs.map +1 -1
- package/build/modern/useQueries.d.cts +4 -4
- package/build/modern/useQueries.d.ts +4 -4
- package/build/modern/useQueries.js.map +1 -1
- package/build/modern/useQuery.cjs.map +1 -1
- package/build/modern/useQuery.d.cts +2 -1
- package/build/modern/useQuery.d.ts +2 -1
- package/build/modern/useQuery.js.map +1 -1
- package/build/modern/useSuspenseQueries.cjs +46 -0
- package/build/modern/useSuspenseQueries.cjs.map +1 -0
- package/build/modern/useSuspenseQueries.d.cts +66 -0
- package/build/modern/useSuspenseQueries.d.ts +66 -0
- package/build/modern/useSuspenseQueries.js +22 -0
- package/build/modern/useSuspenseQueries.js.map +1 -0
- package/build/modern/utils.cjs.map +1 -1
- package/build/modern/utils.d.cts +1 -1
- package/build/modern/utils.d.ts +1 -1
- package/build/modern/utils.js.map +1 -1
- package/package.json +8 -4
- package/src/__tests__/QueryResetErrorBoundary.test.tsx +10 -6
- package/src/__tests__/ssr.test.tsx +2 -2
- package/src/__tests__/suspense.test.tsx +34 -393
- package/src/__tests__/useInfiniteQuery.test.tsx +44 -44
- package/src/__tests__/useInfiniteQuery.type.test.tsx +24 -13
- package/src/__tests__/useIsFetching.test.tsx +2 -2
- package/src/__tests__/useMutation.test.tsx +4 -4
- package/src/__tests__/useMutationState.test.tsx +4 -4
- package/src/__tests__/useQueries.test.tsx +14 -12
- package/src/__tests__/useQuery.test.tsx +109 -80
- package/src/__tests__/useQuery.types.test.tsx +36 -55
- package/src/index.ts +13 -0
- package/src/infiniteQueryOptions.ts +3 -1
- package/src/queryOptions.ts +19 -7
- package/src/types.ts +18 -12
- package/src/useInfiniteQuery.ts +7 -2
- package/src/useQueries.ts +34 -28
- package/src/useQuery.ts +3 -1
- package/src/useSuspenseQueries.ts +163 -0
- package/src/utils.ts +1 -1
|
@@ -5,21 +5,25 @@ import { vi } from 'vitest'
|
|
|
5
5
|
import {
|
|
6
6
|
QueryCache,
|
|
7
7
|
QueryErrorResetBoundary,
|
|
8
|
-
useInfiniteQuery,
|
|
9
|
-
useQueries,
|
|
10
|
-
useQuery,
|
|
11
8
|
useQueryErrorResetBoundary,
|
|
9
|
+
useSuspenseInfiniteQuery,
|
|
10
|
+
useSuspenseQueries,
|
|
11
|
+
useSuspenseQuery,
|
|
12
12
|
} from '..'
|
|
13
13
|
import { createQueryClient, queryKey, renderWithClient, sleep } from './utils'
|
|
14
|
-
import type {
|
|
14
|
+
import type {
|
|
15
|
+
InfiniteData,
|
|
16
|
+
UseSuspenseInfiniteQueryResult,
|
|
17
|
+
UseSuspenseQueryResult,
|
|
18
|
+
} from '..'
|
|
15
19
|
|
|
16
|
-
describe(
|
|
20
|
+
describe('useSuspenseQuery', () => {
|
|
17
21
|
const queryCache = new QueryCache()
|
|
18
22
|
const queryClient = createQueryClient({ queryCache })
|
|
19
23
|
|
|
20
24
|
it('should render the correct amount of times in Suspense mode', async () => {
|
|
21
25
|
const key = queryKey()
|
|
22
|
-
const states:
|
|
26
|
+
const states: Array<UseSuspenseQueryResult<number>> = []
|
|
23
27
|
|
|
24
28
|
let count = 0
|
|
25
29
|
let renders = 0
|
|
@@ -29,14 +33,13 @@ describe("useQuery's in Suspense mode", () => {
|
|
|
29
33
|
|
|
30
34
|
const [stateKey, setStateKey] = React.useState(key)
|
|
31
35
|
|
|
32
|
-
const state =
|
|
36
|
+
const state = useSuspenseQuery({
|
|
33
37
|
queryKey: stateKey,
|
|
34
38
|
queryFn: async () => {
|
|
35
39
|
count++
|
|
36
40
|
await sleep(10)
|
|
37
41
|
return count
|
|
38
42
|
},
|
|
39
|
-
suspense: true,
|
|
40
43
|
})
|
|
41
44
|
|
|
42
45
|
states.push(state)
|
|
@@ -69,18 +72,18 @@ describe("useQuery's in Suspense mode", () => {
|
|
|
69
72
|
|
|
70
73
|
it('should return the correct states for a successful infinite query', async () => {
|
|
71
74
|
const key = queryKey()
|
|
72
|
-
const states:
|
|
75
|
+
const states: Array<UseSuspenseInfiniteQueryResult<InfiniteData<number>>> =
|
|
76
|
+
[]
|
|
73
77
|
|
|
74
78
|
function Page() {
|
|
75
79
|
const [multiplier, setMultiplier] = React.useState(1)
|
|
76
|
-
const state =
|
|
80
|
+
const state = useSuspenseInfiniteQuery({
|
|
77
81
|
queryKey: [`${key}_${multiplier}`],
|
|
78
82
|
queryFn: async ({ pageParam }) => {
|
|
79
83
|
await sleep(10)
|
|
80
84
|
return Number(pageParam * multiplier)
|
|
81
85
|
},
|
|
82
|
-
|
|
83
|
-
defaultPageParam: 1,
|
|
86
|
+
initialPageParam: 1,
|
|
84
87
|
getNextPageParam: (lastPage) => lastPage + 1,
|
|
85
88
|
})
|
|
86
89
|
states.push(state)
|
|
@@ -120,14 +123,14 @@ describe("useQuery's in Suspense mode", () => {
|
|
|
120
123
|
it('should not call the queryFn twice when used in Suspense mode', async () => {
|
|
121
124
|
const key = queryKey()
|
|
122
125
|
|
|
123
|
-
const queryFn = vi.fn<unknown
|
|
126
|
+
const queryFn = vi.fn<Array<unknown>, string>()
|
|
124
127
|
queryFn.mockImplementation(() => {
|
|
125
128
|
sleep(10)
|
|
126
129
|
return 'data'
|
|
127
130
|
})
|
|
128
131
|
|
|
129
132
|
function Page() {
|
|
130
|
-
|
|
133
|
+
useSuspenseQuery({ queryKey: [key], queryFn })
|
|
131
134
|
|
|
132
135
|
return <>rendered</>
|
|
133
136
|
}
|
|
@@ -148,13 +151,12 @@ describe("useQuery's in Suspense mode", () => {
|
|
|
148
151
|
const key = queryKey()
|
|
149
152
|
|
|
150
153
|
function Page() {
|
|
151
|
-
|
|
154
|
+
useSuspenseQuery({
|
|
152
155
|
queryKey: key,
|
|
153
156
|
queryFn: () => {
|
|
154
157
|
sleep(10)
|
|
155
158
|
return 'data'
|
|
156
159
|
},
|
|
157
|
-
suspense: true,
|
|
158
160
|
})
|
|
159
161
|
|
|
160
162
|
return <>rendered</>
|
|
@@ -200,7 +202,7 @@ describe("useQuery's in Suspense mode", () => {
|
|
|
200
202
|
let succeed = false
|
|
201
203
|
|
|
202
204
|
function Page() {
|
|
203
|
-
|
|
205
|
+
useSuspenseQuery({
|
|
204
206
|
queryKey: key,
|
|
205
207
|
queryFn: async () => {
|
|
206
208
|
await sleep(10)
|
|
@@ -212,7 +214,6 @@ describe("useQuery's in Suspense mode", () => {
|
|
|
212
214
|
}
|
|
213
215
|
},
|
|
214
216
|
retryDelay: 10,
|
|
215
|
-
suspense: true,
|
|
216
217
|
})
|
|
217
218
|
|
|
218
219
|
return <div>rendered</div>
|
|
@@ -272,7 +273,7 @@ describe("useQuery's in Suspense mode", () => {
|
|
|
272
273
|
let succeed = false
|
|
273
274
|
|
|
274
275
|
function Page() {
|
|
275
|
-
|
|
276
|
+
useSuspenseQuery({
|
|
276
277
|
queryKey: key,
|
|
277
278
|
queryFn: async () => {
|
|
278
279
|
await sleep(10)
|
|
@@ -283,7 +284,6 @@ describe("useQuery's in Suspense mode", () => {
|
|
|
283
284
|
}
|
|
284
285
|
},
|
|
285
286
|
retry: false,
|
|
286
|
-
suspense: true,
|
|
287
287
|
})
|
|
288
288
|
return <div>rendered</div>
|
|
289
289
|
}
|
|
@@ -332,7 +332,7 @@ describe("useQuery's in Suspense mode", () => {
|
|
|
332
332
|
let count = 0
|
|
333
333
|
|
|
334
334
|
function Component() {
|
|
335
|
-
const result =
|
|
335
|
+
const result = useSuspenseQuery({
|
|
336
336
|
queryKey: key,
|
|
337
337
|
queryFn: async () => {
|
|
338
338
|
await sleep(100)
|
|
@@ -340,7 +340,6 @@ describe("useQuery's in Suspense mode", () => {
|
|
|
340
340
|
return count
|
|
341
341
|
},
|
|
342
342
|
retry: false,
|
|
343
|
-
suspense: true,
|
|
344
343
|
staleTime: 0,
|
|
345
344
|
})
|
|
346
345
|
return (
|
|
@@ -388,7 +387,7 @@ describe("useQuery's in Suspense mode", () => {
|
|
|
388
387
|
const key2 = queryKey()
|
|
389
388
|
|
|
390
389
|
function Component(props: { queryKey: Array<string> }) {
|
|
391
|
-
const result =
|
|
390
|
+
const result = useSuspenseQuery({
|
|
392
391
|
queryKey: props.queryKey,
|
|
393
392
|
queryFn: async () => {
|
|
394
393
|
await sleep(100)
|
|
@@ -396,7 +395,6 @@ describe("useQuery's in Suspense mode", () => {
|
|
|
396
395
|
},
|
|
397
396
|
|
|
398
397
|
retry: false,
|
|
399
|
-
suspense: true,
|
|
400
398
|
})
|
|
401
399
|
return <div>data: {result.data}</div>
|
|
402
400
|
}
|
|
@@ -437,7 +435,7 @@ describe("useQuery's in Suspense mode", () => {
|
|
|
437
435
|
let succeed = false
|
|
438
436
|
|
|
439
437
|
function Page() {
|
|
440
|
-
|
|
438
|
+
useSuspenseQuery({
|
|
441
439
|
queryKey: key,
|
|
442
440
|
queryFn: async () => {
|
|
443
441
|
await sleep(10)
|
|
@@ -448,7 +446,6 @@ describe("useQuery's in Suspense mode", () => {
|
|
|
448
446
|
}
|
|
449
447
|
},
|
|
450
448
|
retry: false,
|
|
451
|
-
suspense: true,
|
|
452
449
|
})
|
|
453
450
|
return <div>rendered</div>
|
|
454
451
|
}
|
|
@@ -499,14 +496,13 @@ describe("useQuery's in Suspense mode", () => {
|
|
|
499
496
|
const key = queryKey()
|
|
500
497
|
|
|
501
498
|
function Page() {
|
|
502
|
-
|
|
499
|
+
useSuspenseQuery({
|
|
503
500
|
queryKey: key,
|
|
504
501
|
queryFn: async (): Promise<unknown> => {
|
|
505
502
|
await sleep(10)
|
|
506
503
|
throw new Error('Suspense Error a1x')
|
|
507
504
|
},
|
|
508
505
|
retry: false,
|
|
509
|
-
suspense: true,
|
|
510
506
|
})
|
|
511
507
|
return <div>rendered</div>
|
|
512
508
|
}
|
|
@@ -534,171 +530,6 @@ describe("useQuery's in Suspense mode", () => {
|
|
|
534
530
|
consoleMock.mockRestore()
|
|
535
531
|
})
|
|
536
532
|
|
|
537
|
-
it('should not throw errors to the error boundary when throwOnError: false', async () => {
|
|
538
|
-
const key = queryKey()
|
|
539
|
-
|
|
540
|
-
function Page() {
|
|
541
|
-
useQuery({
|
|
542
|
-
queryKey: key,
|
|
543
|
-
queryFn: async (): Promise<unknown> => {
|
|
544
|
-
await sleep(10)
|
|
545
|
-
throw new Error('Suspense Error a2x')
|
|
546
|
-
},
|
|
547
|
-
retry: false,
|
|
548
|
-
suspense: true,
|
|
549
|
-
throwOnError: false,
|
|
550
|
-
})
|
|
551
|
-
return <div>rendered</div>
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
function App() {
|
|
555
|
-
return (
|
|
556
|
-
<ErrorBoundary
|
|
557
|
-
fallbackRender={() => (
|
|
558
|
-
<div>
|
|
559
|
-
<div>error boundary</div>
|
|
560
|
-
</div>
|
|
561
|
-
)}
|
|
562
|
-
>
|
|
563
|
-
<React.Suspense fallback="Loading...">
|
|
564
|
-
<Page />
|
|
565
|
-
</React.Suspense>
|
|
566
|
-
</ErrorBoundary>
|
|
567
|
-
)
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
const rendered = renderWithClient(queryClient, <App />)
|
|
571
|
-
|
|
572
|
-
await waitFor(() => rendered.getByText('Loading...'))
|
|
573
|
-
await waitFor(() => rendered.getByText('rendered'))
|
|
574
|
-
})
|
|
575
|
-
|
|
576
|
-
it('should throw errors to the error boundary when a throwOnError function returns true', async () => {
|
|
577
|
-
const consoleMock = vi
|
|
578
|
-
.spyOn(console, 'error')
|
|
579
|
-
.mockImplementation(() => undefined)
|
|
580
|
-
const key = queryKey()
|
|
581
|
-
|
|
582
|
-
function Page() {
|
|
583
|
-
useQuery({
|
|
584
|
-
queryKey: key,
|
|
585
|
-
queryFn: async (): Promise<unknown> => {
|
|
586
|
-
await sleep(10)
|
|
587
|
-
return Promise.reject(new Error('Remote Error'))
|
|
588
|
-
},
|
|
589
|
-
retry: false,
|
|
590
|
-
suspense: true,
|
|
591
|
-
throwOnError: (err) => err.message !== 'Local Error',
|
|
592
|
-
})
|
|
593
|
-
return <div>rendered</div>
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
function App() {
|
|
597
|
-
return (
|
|
598
|
-
<ErrorBoundary
|
|
599
|
-
fallbackRender={() => (
|
|
600
|
-
<div>
|
|
601
|
-
<div>error boundary</div>
|
|
602
|
-
</div>
|
|
603
|
-
)}
|
|
604
|
-
>
|
|
605
|
-
<React.Suspense fallback="Loading...">
|
|
606
|
-
<Page />
|
|
607
|
-
</React.Suspense>
|
|
608
|
-
</ErrorBoundary>
|
|
609
|
-
)
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
const rendered = renderWithClient(queryClient, <App />)
|
|
613
|
-
|
|
614
|
-
await waitFor(() => rendered.getByText('Loading...'))
|
|
615
|
-
await waitFor(() => rendered.getByText('error boundary'))
|
|
616
|
-
consoleMock.mockRestore()
|
|
617
|
-
})
|
|
618
|
-
|
|
619
|
-
it('should not throw errors to the error boundary when a throwOnError function returns false', async () => {
|
|
620
|
-
const key = queryKey()
|
|
621
|
-
|
|
622
|
-
function Page() {
|
|
623
|
-
useQuery({
|
|
624
|
-
queryKey: key,
|
|
625
|
-
queryFn: async (): Promise<unknown> => {
|
|
626
|
-
await sleep(10)
|
|
627
|
-
return Promise.reject(new Error('Local Error'))
|
|
628
|
-
},
|
|
629
|
-
retry: false,
|
|
630
|
-
suspense: true,
|
|
631
|
-
throwOnError: (err) => err.message !== 'Local Error',
|
|
632
|
-
})
|
|
633
|
-
return <div>rendered</div>
|
|
634
|
-
}
|
|
635
|
-
|
|
636
|
-
function App() {
|
|
637
|
-
return (
|
|
638
|
-
<ErrorBoundary
|
|
639
|
-
fallbackRender={() => (
|
|
640
|
-
<div>
|
|
641
|
-
<div>error boundary</div>
|
|
642
|
-
</div>
|
|
643
|
-
)}
|
|
644
|
-
>
|
|
645
|
-
<React.Suspense fallback="Loading...">
|
|
646
|
-
<Page />
|
|
647
|
-
</React.Suspense>
|
|
648
|
-
</ErrorBoundary>
|
|
649
|
-
)
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
const rendered = renderWithClient(queryClient, <App />)
|
|
653
|
-
|
|
654
|
-
await waitFor(() => rendered.getByText('Loading...'))
|
|
655
|
-
await waitFor(() => rendered.getByText('rendered'))
|
|
656
|
-
})
|
|
657
|
-
|
|
658
|
-
it('should not call the queryFn when not enabled', async () => {
|
|
659
|
-
const key = queryKey()
|
|
660
|
-
|
|
661
|
-
const queryFn = vi.fn<unknown[], Promise<string>>()
|
|
662
|
-
queryFn.mockImplementation(async () => {
|
|
663
|
-
await sleep(10)
|
|
664
|
-
return '23'
|
|
665
|
-
})
|
|
666
|
-
|
|
667
|
-
function Page() {
|
|
668
|
-
const [enabled, setEnabled] = React.useState(false)
|
|
669
|
-
const result = useQuery({
|
|
670
|
-
queryKey: [key],
|
|
671
|
-
queryFn,
|
|
672
|
-
suspense: true,
|
|
673
|
-
enabled,
|
|
674
|
-
})
|
|
675
|
-
|
|
676
|
-
return (
|
|
677
|
-
<div>
|
|
678
|
-
<button onClick={() => setEnabled(true)}>fire</button>
|
|
679
|
-
<h1>{result.data}</h1>
|
|
680
|
-
</div>
|
|
681
|
-
)
|
|
682
|
-
}
|
|
683
|
-
|
|
684
|
-
const rendered = renderWithClient(
|
|
685
|
-
queryClient,
|
|
686
|
-
<React.Suspense fallback="loading">
|
|
687
|
-
<Page />
|
|
688
|
-
</React.Suspense>,
|
|
689
|
-
)
|
|
690
|
-
|
|
691
|
-
expect(queryFn).toHaveBeenCalledTimes(0)
|
|
692
|
-
|
|
693
|
-
fireEvent.click(rendered.getByRole('button', { name: /fire/i }))
|
|
694
|
-
|
|
695
|
-
await waitFor(() => {
|
|
696
|
-
expect(rendered.getByRole('heading').textContent).toBe('23')
|
|
697
|
-
})
|
|
698
|
-
|
|
699
|
-
expect(queryFn).toHaveBeenCalledTimes(1)
|
|
700
|
-
})
|
|
701
|
-
|
|
702
533
|
it('should error catched in error boundary without infinite loop', async () => {
|
|
703
534
|
const consoleMock = vi
|
|
704
535
|
.spyOn(console, 'error')
|
|
@@ -710,7 +541,7 @@ describe("useQuery's in Suspense mode", () => {
|
|
|
710
541
|
function Page() {
|
|
711
542
|
const [nonce] = React.useState(0)
|
|
712
543
|
const queryKeys = [`${key}-${succeed}`]
|
|
713
|
-
const result =
|
|
544
|
+
const result = useSuspenseQuery({
|
|
714
545
|
queryKey: queryKeys,
|
|
715
546
|
queryFn: async () => {
|
|
716
547
|
await sleep(10)
|
|
@@ -721,7 +552,6 @@ describe("useQuery's in Suspense mode", () => {
|
|
|
721
552
|
}
|
|
722
553
|
},
|
|
723
554
|
retry: false,
|
|
724
|
-
suspense: true,
|
|
725
555
|
})
|
|
726
556
|
return (
|
|
727
557
|
<div>
|
|
@@ -782,7 +612,7 @@ describe("useQuery's in Suspense mode", () => {
|
|
|
782
612
|
const [key, rerender] = React.useReducer((x) => x + 1, 0)
|
|
783
613
|
const queryKeys = [key, succeed]
|
|
784
614
|
|
|
785
|
-
const result =
|
|
615
|
+
const result = useSuspenseQuery({
|
|
786
616
|
queryKey: queryKeys,
|
|
787
617
|
queryFn: async () => {
|
|
788
618
|
await sleep(10)
|
|
@@ -793,7 +623,6 @@ describe("useQuery's in Suspense mode", () => {
|
|
|
793
623
|
}
|
|
794
624
|
},
|
|
795
625
|
retry: false,
|
|
796
|
-
suspense: true,
|
|
797
626
|
})
|
|
798
627
|
return (
|
|
799
628
|
<div>
|
|
@@ -839,77 +668,9 @@ describe("useQuery's in Suspense mode", () => {
|
|
|
839
668
|
consoleMock.mockRestore()
|
|
840
669
|
})
|
|
841
670
|
|
|
842
|
-
it('should error catched in error boundary without infinite loop when enabled changed', async () => {
|
|
843
|
-
const consoleMock = vi
|
|
844
|
-
.spyOn(console, 'error')
|
|
845
|
-
.mockImplementation(() => undefined)
|
|
846
|
-
function Page() {
|
|
847
|
-
const queryKeys = '1'
|
|
848
|
-
const [enabled, setEnabled] = React.useState(false)
|
|
849
|
-
|
|
850
|
-
const result = useQuery<string>({
|
|
851
|
-
queryKey: [queryKeys],
|
|
852
|
-
queryFn: async () => {
|
|
853
|
-
await sleep(10)
|
|
854
|
-
throw new Error('Suspense Error Bingo')
|
|
855
|
-
},
|
|
856
|
-
|
|
857
|
-
retry: false,
|
|
858
|
-
suspense: true,
|
|
859
|
-
enabled,
|
|
860
|
-
})
|
|
861
|
-
return (
|
|
862
|
-
<div>
|
|
863
|
-
<span>rendered</span> <span>{result.data}</span>
|
|
864
|
-
<button
|
|
865
|
-
aria-label="fail"
|
|
866
|
-
onClick={() => {
|
|
867
|
-
setEnabled(true)
|
|
868
|
-
}}
|
|
869
|
-
>
|
|
870
|
-
fail
|
|
871
|
-
</button>
|
|
872
|
-
</div>
|
|
873
|
-
)
|
|
874
|
-
}
|
|
875
|
-
|
|
876
|
-
function App() {
|
|
877
|
-
const { reset } = useQueryErrorResetBoundary()
|
|
878
|
-
return (
|
|
879
|
-
<ErrorBoundary
|
|
880
|
-
onReset={reset}
|
|
881
|
-
fallbackRender={() => <div>error boundary</div>}
|
|
882
|
-
>
|
|
883
|
-
<React.Suspense fallback="Loading...">
|
|
884
|
-
<Page />
|
|
885
|
-
</React.Suspense>
|
|
886
|
-
</ErrorBoundary>
|
|
887
|
-
)
|
|
888
|
-
}
|
|
889
|
-
|
|
890
|
-
const rendered = renderWithClient(queryClient, <App />)
|
|
891
|
-
|
|
892
|
-
// render empty data with 'rendered' when enabled is false
|
|
893
|
-
await waitFor(() => rendered.getByText('rendered'))
|
|
894
|
-
|
|
895
|
-
// change enabled to true
|
|
896
|
-
fireEvent.click(rendered.getByLabelText('fail'))
|
|
897
|
-
|
|
898
|
-
// render pending fallback
|
|
899
|
-
await waitFor(() => rendered.getByText('Loading...'))
|
|
900
|
-
|
|
901
|
-
// render error boundary fallback (error boundary)
|
|
902
|
-
await waitFor(() => rendered.getByText('error boundary'))
|
|
903
|
-
expect(consoleMock).toHaveBeenCalledWith(
|
|
904
|
-
expect.objectContaining(new Error('Suspense Error Bingo')),
|
|
905
|
-
)
|
|
906
|
-
|
|
907
|
-
consoleMock.mockRestore()
|
|
908
|
-
})
|
|
909
|
-
|
|
910
671
|
it('should render the correct amount of times in Suspense mode when gcTime is set to 0', async () => {
|
|
911
672
|
const key = queryKey()
|
|
912
|
-
let state:
|
|
673
|
+
let state: UseSuspenseQueryResult<number> | null = null
|
|
913
674
|
|
|
914
675
|
let count = 0
|
|
915
676
|
let renders = 0
|
|
@@ -917,14 +678,13 @@ describe("useQuery's in Suspense mode", () => {
|
|
|
917
678
|
function Page() {
|
|
918
679
|
renders++
|
|
919
680
|
|
|
920
|
-
state =
|
|
681
|
+
state = useSuspenseQuery({
|
|
921
682
|
queryKey: key,
|
|
922
683
|
queryFn: async () => {
|
|
923
684
|
count++
|
|
924
685
|
await sleep(10)
|
|
925
686
|
return count
|
|
926
687
|
},
|
|
927
|
-
suspense: true,
|
|
928
688
|
gcTime: 0,
|
|
929
689
|
})
|
|
930
690
|
|
|
@@ -954,12 +714,12 @@ describe("useQuery's in Suspense mode", () => {
|
|
|
954
714
|
})
|
|
955
715
|
})
|
|
956
716
|
|
|
957
|
-
describe('
|
|
717
|
+
describe('useSuspenseQueries', () => {
|
|
958
718
|
const queryClient = createQueryClient()
|
|
959
719
|
it('should suspend all queries in parallel', async () => {
|
|
960
720
|
const key1 = queryKey()
|
|
961
721
|
const key2 = queryKey()
|
|
962
|
-
const results: string
|
|
722
|
+
const results: Array<string> = []
|
|
963
723
|
|
|
964
724
|
function Fallback() {
|
|
965
725
|
results.push('loading')
|
|
@@ -967,7 +727,7 @@ describe('useQueries with suspense', () => {
|
|
|
967
727
|
}
|
|
968
728
|
|
|
969
729
|
function Page() {
|
|
970
|
-
const result =
|
|
730
|
+
const result = useSuspenseQueries({
|
|
971
731
|
queries: [
|
|
972
732
|
{
|
|
973
733
|
queryKey: key1,
|
|
@@ -976,7 +736,6 @@ describe('useQueries with suspense', () => {
|
|
|
976
736
|
await sleep(10)
|
|
977
737
|
return '1'
|
|
978
738
|
},
|
|
979
|
-
suspense: true,
|
|
980
739
|
},
|
|
981
740
|
{
|
|
982
741
|
queryKey: key2,
|
|
@@ -985,7 +744,6 @@ describe('useQueries with suspense', () => {
|
|
|
985
744
|
await sleep(20)
|
|
986
745
|
return '2'
|
|
987
746
|
},
|
|
988
|
-
suspense: true,
|
|
989
747
|
},
|
|
990
748
|
],
|
|
991
749
|
})
|
|
@@ -1009,68 +767,11 @@ describe('useQueries with suspense', () => {
|
|
|
1009
767
|
expect(results).toEqual(['1', '2', 'loading'])
|
|
1010
768
|
})
|
|
1011
769
|
|
|
1012
|
-
it('should allow to mix suspense with non-suspense', async () => {
|
|
1013
|
-
const key1 = queryKey()
|
|
1014
|
-
const key2 = queryKey()
|
|
1015
|
-
const results: string[] = []
|
|
1016
|
-
|
|
1017
|
-
function Fallback() {
|
|
1018
|
-
results.push('loading')
|
|
1019
|
-
return <div>loading</div>
|
|
1020
|
-
}
|
|
1021
|
-
|
|
1022
|
-
function Page() {
|
|
1023
|
-
const result = useQueries({
|
|
1024
|
-
queries: [
|
|
1025
|
-
{
|
|
1026
|
-
queryKey: key1,
|
|
1027
|
-
queryFn: async () => {
|
|
1028
|
-
results.push('1')
|
|
1029
|
-
await sleep(50)
|
|
1030
|
-
return '1'
|
|
1031
|
-
},
|
|
1032
|
-
suspense: true,
|
|
1033
|
-
},
|
|
1034
|
-
{
|
|
1035
|
-
queryKey: key2,
|
|
1036
|
-
queryFn: async () => {
|
|
1037
|
-
results.push('2')
|
|
1038
|
-
await sleep(200)
|
|
1039
|
-
return '2'
|
|
1040
|
-
},
|
|
1041
|
-
staleTime: 2000,
|
|
1042
|
-
suspense: false,
|
|
1043
|
-
},
|
|
1044
|
-
],
|
|
1045
|
-
})
|
|
1046
|
-
|
|
1047
|
-
return (
|
|
1048
|
-
<div>
|
|
1049
|
-
<h1>data: {result.map((it) => it.data ?? 'null').join(',')}</h1>
|
|
1050
|
-
<h2>status: {result.map((it) => it.status).join(',')}</h2>
|
|
1051
|
-
</div>
|
|
1052
|
-
)
|
|
1053
|
-
}
|
|
1054
|
-
|
|
1055
|
-
const rendered = renderWithClient(
|
|
1056
|
-
queryClient,
|
|
1057
|
-
<React.Suspense fallback={<Fallback />}>
|
|
1058
|
-
<Page />
|
|
1059
|
-
</React.Suspense>,
|
|
1060
|
-
)
|
|
1061
|
-
await waitFor(() => rendered.getByText('loading'))
|
|
1062
|
-
await waitFor(() => rendered.getByText('status: success,pending'))
|
|
1063
|
-
await waitFor(() => rendered.getByText('data: 1,null'))
|
|
1064
|
-
await waitFor(() => rendered.getByText('data: 1,2'))
|
|
1065
|
-
|
|
1066
|
-
expect(results).toEqual(['1', '2', 'loading'])
|
|
1067
|
-
})
|
|
1068
|
-
|
|
1069
770
|
it("shouldn't unmount before all promises fetched", async () => {
|
|
1070
771
|
const key1 = queryKey()
|
|
1071
772
|
const key2 = queryKey()
|
|
1072
|
-
const results: string
|
|
1073
|
-
const refs: number
|
|
773
|
+
const results: Array<string> = []
|
|
774
|
+
const refs: Array<number> = []
|
|
1074
775
|
|
|
1075
776
|
function Fallback() {
|
|
1076
777
|
results.push('loading')
|
|
@@ -1079,7 +780,7 @@ describe('useQueries with suspense', () => {
|
|
|
1079
780
|
|
|
1080
781
|
function Page() {
|
|
1081
782
|
const ref = React.useRef(Math.random())
|
|
1082
|
-
const result =
|
|
783
|
+
const result = useSuspenseQueries({
|
|
1083
784
|
queries: [
|
|
1084
785
|
{
|
|
1085
786
|
queryKey: key1,
|
|
@@ -1089,7 +790,6 @@ describe('useQueries with suspense', () => {
|
|
|
1089
790
|
await sleep(10)
|
|
1090
791
|
return '1'
|
|
1091
792
|
},
|
|
1092
|
-
suspense: true,
|
|
1093
793
|
},
|
|
1094
794
|
{
|
|
1095
795
|
queryKey: key2,
|
|
@@ -1099,7 +799,6 @@ describe('useQueries with suspense', () => {
|
|
|
1099
799
|
await sleep(20)
|
|
1100
800
|
return '2'
|
|
1101
801
|
},
|
|
1102
|
-
suspense: true,
|
|
1103
802
|
},
|
|
1104
803
|
],
|
|
1105
804
|
})
|
|
@@ -1121,62 +820,4 @@ describe('useQueries with suspense', () => {
|
|
|
1121
820
|
await waitFor(() => rendered.getByText('data: 1,2'))
|
|
1122
821
|
expect(refs[0]).toBe(refs[1])
|
|
1123
822
|
})
|
|
1124
|
-
|
|
1125
|
-
it('should suspend all queries in parallel - global configuration', async () => {
|
|
1126
|
-
const queryClientSuspenseMode = createQueryClient({
|
|
1127
|
-
defaultOptions: {
|
|
1128
|
-
queries: {
|
|
1129
|
-
suspense: true,
|
|
1130
|
-
},
|
|
1131
|
-
},
|
|
1132
|
-
})
|
|
1133
|
-
const key1 = queryKey()
|
|
1134
|
-
const key2 = queryKey()
|
|
1135
|
-
const results: string[] = []
|
|
1136
|
-
|
|
1137
|
-
function Fallback() {
|
|
1138
|
-
results.push('loading')
|
|
1139
|
-
return <div>loading</div>
|
|
1140
|
-
}
|
|
1141
|
-
|
|
1142
|
-
function Page() {
|
|
1143
|
-
const result = useQueries({
|
|
1144
|
-
queries: [
|
|
1145
|
-
{
|
|
1146
|
-
queryKey: key1,
|
|
1147
|
-
queryFn: async () => {
|
|
1148
|
-
results.push('1')
|
|
1149
|
-
await sleep(10)
|
|
1150
|
-
return '1'
|
|
1151
|
-
},
|
|
1152
|
-
},
|
|
1153
|
-
{
|
|
1154
|
-
queryKey: key2,
|
|
1155
|
-
queryFn: async () => {
|
|
1156
|
-
results.push('2')
|
|
1157
|
-
await sleep(20)
|
|
1158
|
-
return '2'
|
|
1159
|
-
},
|
|
1160
|
-
},
|
|
1161
|
-
],
|
|
1162
|
-
})
|
|
1163
|
-
return (
|
|
1164
|
-
<div>
|
|
1165
|
-
<h1>data: {result.map((it) => it.data ?? 'null').join(',')}</h1>
|
|
1166
|
-
</div>
|
|
1167
|
-
)
|
|
1168
|
-
}
|
|
1169
|
-
|
|
1170
|
-
const rendered = renderWithClient(
|
|
1171
|
-
queryClientSuspenseMode,
|
|
1172
|
-
<React.Suspense fallback={<Fallback />}>
|
|
1173
|
-
<Page />
|
|
1174
|
-
</React.Suspense>,
|
|
1175
|
-
)
|
|
1176
|
-
|
|
1177
|
-
await waitFor(() => rendered.getByText('loading'))
|
|
1178
|
-
await waitFor(() => rendered.getByText('data: 1,2'))
|
|
1179
|
-
|
|
1180
|
-
expect(results).toEqual(['1', '2', 'loading'])
|
|
1181
|
-
})
|
|
1182
823
|
})
|