@tanstack/react-query 5.0.0-alpha.6 → 5.0.0-alpha.61
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/codemods/__testfixtures__/default-import.input.tsx +94 -0
- package/build/codemods/__testfixtures__/default-import.output.tsx +96 -0
- package/build/codemods/__testfixtures__/named-import.input.tsx +96 -0
- package/build/codemods/__testfixtures__/named-import.output.tsx +98 -0
- package/build/codemods/__testfixtures__/namespaced-import.input.tsx +86 -0
- package/build/codemods/__testfixtures__/namespaced-import.output.tsx +88 -0
- package/build/codemods/__testfixtures__/parameter-is-identifier.input.tsx +49 -0
- package/build/codemods/__testfixtures__/parameter-is-identifier.output.tsx +49 -0
- package/build/codemods/__testfixtures__/parameter-is-object-expression.input.tsx +128 -0
- package/build/codemods/__testfixtures__/parameter-is-object-expression.output.tsx +175 -0
- package/build/codemods/__testfixtures__/replace-import-specifier.input.tsx +10 -0
- package/build/codemods/__testfixtures__/replace-import-specifier.output.tsx +10 -0
- package/build/codemods/__testfixtures__/type-arguments.input.tsx +25 -0
- package/build/codemods/__testfixtures__/type-arguments.output.tsx +31 -0
- package/build/codemods/__tests__/key-transformation.test.js +32 -0
- package/build/codemods/__tests__/replace-import-specifier.test.js +12 -0
- package/build/codemods/remove-overloads/__testfixtures__/default-import.input.tsx +199 -0
- package/build/codemods/remove-overloads/__testfixtures__/default-import.output.tsx +484 -0
- package/build/codemods/remove-overloads/__tests__/remove-overloads.test.js +6 -0
- package/build/codemods/remove-overloads/remove-overloads.js +59 -0
- package/build/codemods/remove-overloads/transformers/filter-aware-usage-transformer.js +153 -0
- package/build/codemods/remove-overloads/transformers/query-fn-aware-usage-transformer.js +188 -0
- package/build/codemods/remove-overloads/utils/index.js +124 -0
- package/build/codemods/remove-overloads/utils/unknown-usage-error.js +27 -0
- package/build/codemods/src/utils/index.js +205 -0
- package/build/codemods/src/v4/key-transformation.js +138 -0
- package/build/codemods/src/v4/replace-import-specifier.js +25 -0
- package/build/codemods/transformers/query-cache-transformer.js +116 -0
- package/build/codemods/transformers/query-client-transformer.js +48 -0
- package/build/codemods/transformers/use-query-like-transformer.js +32 -0
- package/build/codemods/utils/replacers/key-replacer.js +164 -0
- package/build/lib/HydrationBoundary.cjs +50 -0
- package/build/lib/{HydrationBoundary.mjs.map → HydrationBoundary.cjs.map} +1 -1
- package/build/lib/HydrationBoundary.d.ts +1 -0
- package/build/lib/HydrationBoundary.d.ts.map +1 -0
- package/build/lib/HydrationBoundary.js +9 -29
- package/build/lib/HydrationBoundary.js.map +1 -1
- package/build/lib/QueryClientProvider.cjs +54 -0
- package/build/lib/QueryClientProvider.cjs.map +1 -0
- package/build/lib/QueryClientProvider.d.ts +2 -1
- package/build/lib/QueryClientProvider.d.ts.map +1 -0
- package/build/lib/QueryClientProvider.js +7 -29
- package/build/lib/QueryClientProvider.js.map +1 -1
- package/build/lib/QueryErrorResetBoundary.cjs +60 -0
- package/build/lib/{QueryErrorResetBoundary.mjs.map → QueryErrorResetBoundary.cjs.map} +1 -1
- package/build/lib/QueryErrorResetBoundary.d.ts +2 -1
- package/build/lib/QueryErrorResetBoundary.d.ts.map +1 -0
- package/build/lib/QueryErrorResetBoundary.js +7 -28
- package/build/lib/QueryErrorResetBoundary.js.map +1 -1
- package/build/lib/__tests__/HydrationBoundary.test.d.ts +1 -0
- package/build/lib/__tests__/HydrationBoundary.test.d.ts.map +1 -0
- package/build/lib/__tests__/QueryClientProvider.test.d.ts +1 -0
- package/build/lib/__tests__/QueryClientProvider.test.d.ts.map +1 -0
- package/build/lib/__tests__/QueryResetErrorBoundary.test.d.ts +1 -0
- package/build/lib/__tests__/QueryResetErrorBoundary.test.d.ts.map +1 -0
- package/build/lib/__tests__/ssr-hydration.test.d.ts +1 -0
- package/build/lib/__tests__/ssr-hydration.test.d.ts.map +1 -0
- package/build/lib/__tests__/ssr.test.d.ts +1 -0
- package/build/lib/__tests__/ssr.test.d.ts.map +1 -0
- package/build/lib/__tests__/suspense.test.d.ts +1 -0
- package/build/lib/__tests__/suspense.test.d.ts.map +1 -0
- package/build/lib/__tests__/useInfiniteQuery.test.d.ts +1 -0
- package/build/lib/__tests__/useInfiniteQuery.test.d.ts.map +1 -0
- package/build/lib/__tests__/useInfiniteQuery.type.test.d.ts +1 -0
- package/build/lib/__tests__/useInfiniteQuery.type.test.d.ts.map +1 -0
- package/build/lib/__tests__/useIsFetching.test.d.ts +1 -0
- package/build/lib/__tests__/useIsFetching.test.d.ts.map +1 -0
- package/build/lib/__tests__/useMutation.test.d.ts +1 -0
- package/build/lib/__tests__/useMutation.test.d.ts.map +1 -0
- package/build/lib/__tests__/useMutationState.test.d.ts +1 -0
- package/build/lib/__tests__/useMutationState.test.d.ts.map +1 -0
- package/build/lib/__tests__/useQueries.test.d.ts +1 -0
- package/build/lib/__tests__/useQueries.test.d.ts.map +1 -0
- package/build/lib/__tests__/useQuery.test.d.ts +1 -0
- package/build/lib/__tests__/useQuery.test.d.ts.map +1 -0
- package/build/lib/__tests__/useQuery.types.test.d.ts +1 -0
- package/build/lib/__tests__/useQuery.types.test.d.ts.map +1 -0
- package/build/lib/__tests__/utils.d.ts +6 -5
- package/build/lib/__tests__/utils.d.ts.map +1 -0
- package/build/lib/errorBoundaryUtils.cjs +51 -0
- package/build/lib/errorBoundaryUtils.cjs.map +1 -0
- package/build/lib/errorBoundaryUtils.d.ts +4 -3
- package/build/lib/errorBoundaryUtils.d.ts.map +1 -0
- package/build/lib/errorBoundaryUtils.js +8 -30
- package/build/lib/errorBoundaryUtils.js.map +1 -1
- package/build/lib/index.cjs +39 -0
- package/build/lib/index.cjs.map +1 -0
- package/build/lib/index.d.ts +2 -1
- package/build/lib/index.d.ts.map +1 -0
- package/build/lib/index.js +11 -37
- package/build/lib/index.js.map +1 -1
- package/build/lib/isRestoring.cjs +31 -0
- package/build/lib/isRestoring.cjs.map +1 -0
- package/build/lib/isRestoring.d.ts +1 -0
- package/build/lib/isRestoring.d.ts.map +1 -0
- package/build/lib/isRestoring.js +5 -26
- package/build/lib/isRestoring.js.map +1 -1
- package/build/lib/{suspense.mjs → suspense.cjs} +8 -10
- package/build/lib/suspense.cjs.map +1 -0
- package/build/lib/suspense.d.ts +3 -5
- package/build/lib/suspense.d.ts.map +1 -0
- package/build/lib/suspense.js +3 -15
- package/build/lib/suspense.js.map +1 -1
- package/build/lib/types.d.ts +11 -10
- package/build/lib/types.d.ts.map +1 -0
- package/build/lib/useBaseQuery.cjs +80 -0
- package/build/lib/useBaseQuery.cjs.map +1 -0
- package/build/lib/useBaseQuery.d.ts +1 -0
- package/build/lib/useBaseQuery.d.ts.map +1 -0
- package/build/lib/useBaseQuery.js +30 -54
- package/build/lib/useBaseQuery.js.map +1 -1
- package/build/lib/useInfiniteQuery.cjs +15 -0
- package/build/lib/useInfiniteQuery.cjs.map +1 -0
- package/build/lib/useInfiniteQuery.d.ts +1 -0
- package/build/lib/useInfiniteQuery.d.ts.map +1 -0
- package/build/lib/useInfiniteQuery.js +6 -7
- package/build/lib/useInfiniteQuery.js.map +1 -1
- package/build/lib/useIsFetching.cjs +34 -0
- package/build/lib/useIsFetching.cjs.map +1 -0
- package/build/lib/useIsFetching.d.ts +1 -0
- package/build/lib/useIsFetching.d.ts.map +1 -0
- package/build/lib/useIsFetching.js +7 -27
- package/build/lib/useIsFetching.js.map +1 -1
- package/build/lib/useMutation.cjs +54 -0
- package/build/lib/useMutation.cjs.map +1 -0
- package/build/lib/useMutation.d.ts +1 -0
- package/build/lib/useMutation.d.ts.map +1 -0
- package/build/lib/useMutation.js +12 -32
- package/build/lib/useMutation.js.map +1 -1
- package/build/lib/useMutationState.cjs +60 -0
- package/build/lib/useMutationState.cjs.map +1 -0
- package/build/lib/useMutationState.d.ts +4 -3
- package/build/lib/useMutationState.d.ts.map +1 -0
- package/build/lib/useMutationState.js +13 -34
- package/build/lib/useMutationState.js.map +1 -1
- package/build/lib/useQueries.cjs +99 -0
- package/build/lib/useQueries.cjs.map +1 -0
- package/build/lib/useQueries.d.ts +10 -8
- package/build/lib/useQueries.d.ts.map +1 -0
- package/build/lib/useQueries.js +52 -67
- package/build/lib/useQueries.js.map +1 -1
- package/build/lib/useQuery.cjs +19 -0
- package/build/lib/useQuery.cjs.map +1 -0
- package/build/lib/useQuery.d.ts +5 -2
- package/build/lib/useQuery.d.ts.map +1 -0
- package/build/lib/useQuery.js +8 -5
- package/build/lib/useQuery.js.map +1 -1
- package/build/lib/{utils.esm.js → utils.cjs} +4 -2
- package/build/lib/{utils.mjs.map → utils.cjs.map} +1 -1
- package/build/lib/utils.d.ts +1 -0
- package/build/lib/utils.d.ts.map +1 -0
- package/build/lib/utils.js +1 -3
- package/build/lib/utils.js.map +1 -1
- package/package.json +24 -15
- package/src/__tests__/QueryResetErrorBoundary.test.tsx +752 -620
- package/src/__tests__/ssr-hydration.test.tsx +2 -2
- package/src/__tests__/suspense.test.tsx +6 -88
- package/src/__tests__/useInfiniteQuery.type.test.tsx +0 -27
- package/src/__tests__/useMutation.test.tsx +4 -4
- package/src/__tests__/useMutationState.test.tsx +23 -0
- package/src/__tests__/useQueries.test.tsx +206 -83
- package/src/__tests__/useQuery.test.tsx +246 -338
- package/src/__tests__/useQuery.types.test.tsx +21 -1
- package/src/errorBoundaryUtils.ts +6 -5
- package/src/index.ts +1 -1
- package/src/suspense.ts +9 -15
- package/src/useBaseQuery.ts +12 -23
- package/src/useInfiniteQuery.ts +1 -0
- package/src/useIsFetching.ts +1 -0
- package/src/useMutation.ts +2 -1
- package/src/useMutationState.ts +4 -3
- package/src/useQueries.ts +44 -26
- package/src/useQuery.ts +23 -0
- package/build/lib/HydrationBoundary.esm.js +0 -28
- package/build/lib/HydrationBoundary.esm.js.map +0 -1
- package/build/lib/HydrationBoundary.mjs +0 -28
- package/build/lib/QueryClientProvider.esm.js +0 -30
- package/build/lib/QueryClientProvider.esm.js.map +0 -1
- package/build/lib/QueryClientProvider.mjs +0 -30
- package/build/lib/QueryClientProvider.mjs.map +0 -1
- package/build/lib/QueryErrorResetBoundary.esm.js +0 -37
- package/build/lib/QueryErrorResetBoundary.esm.js.map +0 -1
- package/build/lib/QueryErrorResetBoundary.mjs +0 -37
- package/build/lib/errorBoundaryUtils.esm.js +0 -27
- package/build/lib/errorBoundaryUtils.esm.js.map +0 -1
- package/build/lib/errorBoundaryUtils.mjs +0 -27
- package/build/lib/errorBoundaryUtils.mjs.map +0 -1
- package/build/lib/index.esm.js +0 -12
- package/build/lib/index.esm.js.map +0 -1
- package/build/lib/index.mjs +0 -12
- package/build/lib/index.mjs.map +0 -1
- package/build/lib/isRestoring.esm.js +0 -8
- package/build/lib/isRestoring.esm.js.map +0 -1
- package/build/lib/isRestoring.mjs +0 -8
- package/build/lib/isRestoring.mjs.map +0 -1
- package/build/lib/suspense.esm.js +0 -24
- package/build/lib/suspense.esm.js.map +0 -1
- package/build/lib/suspense.mjs.map +0 -1
- package/build/lib/useBaseQuery.esm.js +0 -62
- package/build/lib/useBaseQuery.esm.js.map +0 -1
- package/build/lib/useBaseQuery.mjs +0 -62
- package/build/lib/useBaseQuery.mjs.map +0 -1
- package/build/lib/useInfiniteQuery.esm.js +0 -12
- package/build/lib/useInfiniteQuery.esm.js.map +0 -1
- package/build/lib/useInfiniteQuery.mjs +0 -12
- package/build/lib/useInfiniteQuery.mjs.map +0 -1
- package/build/lib/useIsFetching.esm.js +0 -12
- package/build/lib/useIsFetching.esm.js.map +0 -1
- package/build/lib/useIsFetching.mjs +0 -12
- package/build/lib/useIsFetching.mjs.map +0 -1
- package/build/lib/useMutation.esm.js +0 -32
- package/build/lib/useMutation.esm.js.map +0 -1
- package/build/lib/useMutation.mjs +0 -32
- package/build/lib/useMutation.mjs.map +0 -1
- package/build/lib/useMutationState.esm.js +0 -37
- package/build/lib/useMutationState.esm.js.map +0 -1
- package/build/lib/useMutationState.mjs +0 -37
- package/build/lib/useMutationState.mjs.map +0 -1
- package/build/lib/useQueries.esm.js +0 -72
- package/build/lib/useQueries.esm.js.map +0 -1
- package/build/lib/useQueries.mjs +0 -69
- package/build/lib/useQueries.mjs.map +0 -1
- package/build/lib/useQuery.esm.js +0 -11
- package/build/lib/useQuery.esm.js.map +0 -1
- package/build/lib/useQuery.mjs +0 -11
- package/build/lib/useQuery.mjs.map +0 -1
- package/build/lib/utils.esm.js.map +0 -1
- package/build/lib/utils.mjs +0 -10
- package/build/umd/index.development.js +0 -3040
- package/build/umd/index.development.js.map +0 -1
- package/build/umd/index.production.js +0 -2
- package/build/umd/index.production.js.map +0 -1
|
@@ -3,7 +3,7 @@ import { ErrorBoundary } from 'react-error-boundary'
|
|
|
3
3
|
import * as React from 'react'
|
|
4
4
|
|
|
5
5
|
import { createQueryClient, queryKey, renderWithClient, sleep } from './utils'
|
|
6
|
-
import { QueryCache, QueryErrorResetBoundary, useQuery } from '..'
|
|
6
|
+
import { QueryCache, QueryErrorResetBoundary, useQuery, useQueries } from '..'
|
|
7
7
|
import { vi } from 'vitest'
|
|
8
8
|
|
|
9
9
|
// TODO: This should be removed with the types for react-error-boundary get updated.
|
|
@@ -17,647 +17,779 @@ describe('QueryErrorResetBoundary', () => {
|
|
|
17
17
|
const queryCache = new QueryCache()
|
|
18
18
|
const queryClient = createQueryClient({ queryCache })
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
<div>
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
await waitFor(() => rendered.getByText('error boundary'))
|
|
71
|
-
await waitFor(() => rendered.getByText('retry'))
|
|
72
|
-
succeed = true
|
|
73
|
-
fireEvent.click(rendered.getByText('retry'))
|
|
74
|
-
await waitFor(() => rendered.getByText('data'))
|
|
75
|
-
consoleMock.mockRestore()
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
it('should not throw error if query is disabled', async () => {
|
|
79
|
-
const consoleMock = vi
|
|
80
|
-
.spyOn(console, 'error')
|
|
81
|
-
.mockImplementation(() => undefined)
|
|
82
|
-
const key = queryKey()
|
|
83
|
-
|
|
84
|
-
let succeed = false
|
|
85
|
-
|
|
86
|
-
function Page() {
|
|
87
|
-
const { data, status } = useQuery({
|
|
88
|
-
queryKey: key,
|
|
89
|
-
queryFn: async () => {
|
|
90
|
-
await sleep(10)
|
|
91
|
-
if (!succeed) {
|
|
92
|
-
throw new Error('Error')
|
|
93
|
-
} else {
|
|
94
|
-
return 'data'
|
|
95
|
-
}
|
|
96
|
-
},
|
|
97
|
-
retry: false,
|
|
98
|
-
enabled: !succeed,
|
|
99
|
-
throwErrors: true,
|
|
100
|
-
})
|
|
101
|
-
return (
|
|
102
|
-
<div>
|
|
103
|
-
<div>status: {status}</div>
|
|
104
|
-
<div>{data}</div>
|
|
105
|
-
</div>
|
|
20
|
+
describe('useQuery', () => {
|
|
21
|
+
it('should retry fetch if the reset error boundary has been reset', async () => {
|
|
22
|
+
const consoleMock = vi
|
|
23
|
+
.spyOn(console, 'error')
|
|
24
|
+
.mockImplementation(() => undefined)
|
|
25
|
+
const key = queryKey()
|
|
26
|
+
|
|
27
|
+
let succeed = false
|
|
28
|
+
|
|
29
|
+
function Page() {
|
|
30
|
+
const { data } = useQuery({
|
|
31
|
+
queryKey: key,
|
|
32
|
+
queryFn: async () => {
|
|
33
|
+
await sleep(10)
|
|
34
|
+
if (!succeed) {
|
|
35
|
+
throw new Error('Error')
|
|
36
|
+
} else {
|
|
37
|
+
return 'data'
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
retry: false,
|
|
41
|
+
throwOnError: true,
|
|
42
|
+
})
|
|
43
|
+
return <div>{data}</div>
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const rendered = renderWithClient(
|
|
47
|
+
queryClient,
|
|
48
|
+
<QueryErrorResetBoundary>
|
|
49
|
+
{({ reset }) => (
|
|
50
|
+
<ErrorBoundary
|
|
51
|
+
onReset={reset}
|
|
52
|
+
fallbackRender={({ resetErrorBoundary }) => (
|
|
53
|
+
<div>
|
|
54
|
+
<div>error boundary</div>
|
|
55
|
+
<button
|
|
56
|
+
onClick={() => {
|
|
57
|
+
resetErrorBoundary()
|
|
58
|
+
}}
|
|
59
|
+
>
|
|
60
|
+
retry
|
|
61
|
+
</button>
|
|
62
|
+
</div>
|
|
63
|
+
)}
|
|
64
|
+
>
|
|
65
|
+
<Page />
|
|
66
|
+
</ErrorBoundary>
|
|
67
|
+
)}
|
|
68
|
+
</QueryErrorResetBoundary>,
|
|
106
69
|
)
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
const rendered = renderWithClient(
|
|
110
|
-
queryClient,
|
|
111
|
-
<QueryErrorResetBoundary>
|
|
112
|
-
{({ reset }) => (
|
|
113
|
-
<ErrorBoundary
|
|
114
|
-
onReset={reset}
|
|
115
|
-
fallbackRender={({ resetErrorBoundary }) => (
|
|
116
|
-
<div>
|
|
117
|
-
<div>error boundary</div>
|
|
118
|
-
<button
|
|
119
|
-
onClick={() => {
|
|
120
|
-
resetErrorBoundary()
|
|
121
|
-
}}
|
|
122
|
-
>
|
|
123
|
-
retry
|
|
124
|
-
</button>
|
|
125
|
-
</div>
|
|
126
|
-
)}
|
|
127
|
-
>
|
|
128
|
-
<Page />
|
|
129
|
-
</ErrorBoundary>
|
|
130
|
-
)}
|
|
131
|
-
</QueryErrorResetBoundary>,
|
|
132
|
-
)
|
|
133
|
-
|
|
134
|
-
await waitFor(() => rendered.getByText('error boundary'))
|
|
135
|
-
await waitFor(() => rendered.getByText('retry'))
|
|
136
|
-
succeed = true
|
|
137
|
-
fireEvent.click(rendered.getByText('retry'))
|
|
138
|
-
await waitFor(() => rendered.getByText('status: error'))
|
|
139
|
-
consoleMock.mockRestore()
|
|
140
|
-
})
|
|
141
|
-
|
|
142
|
-
it('should not throw error if query is disabled, and refetch if query becomes enabled again', async () => {
|
|
143
|
-
const consoleMock = vi
|
|
144
|
-
.spyOn(console, 'error')
|
|
145
|
-
.mockImplementation(() => undefined)
|
|
146
|
-
|
|
147
|
-
const key = queryKey()
|
|
148
70
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
fallbackRender={({ resetErrorBoundary }) => (
|
|
182
|
-
<div>
|
|
183
|
-
<div>error boundary</div>
|
|
184
|
-
<button
|
|
185
|
-
onClick={() => {
|
|
186
|
-
resetErrorBoundary()
|
|
187
|
-
}}
|
|
188
|
-
>
|
|
189
|
-
retry
|
|
190
|
-
</button>
|
|
191
|
-
</div>
|
|
192
|
-
)}
|
|
193
|
-
>
|
|
194
|
-
<Page />
|
|
195
|
-
</ErrorBoundary>
|
|
196
|
-
)}
|
|
197
|
-
</QueryErrorResetBoundary>,
|
|
198
|
-
)
|
|
199
|
-
|
|
200
|
-
await waitFor(() => rendered.getByText('error boundary'))
|
|
201
|
-
await waitFor(() => rendered.getByText('retry'))
|
|
202
|
-
succeed = true
|
|
203
|
-
fireEvent.click(rendered.getByText('retry'))
|
|
204
|
-
await waitFor(() => rendered.getByText('data'))
|
|
205
|
-
consoleMock.mockRestore()
|
|
206
|
-
})
|
|
207
|
-
|
|
208
|
-
it('should throw error if query is disabled and manually refetched', async () => {
|
|
209
|
-
const consoleMock = vi
|
|
210
|
-
.spyOn(console, 'error')
|
|
211
|
-
.mockImplementation(() => undefined)
|
|
212
|
-
|
|
213
|
-
const key = queryKey()
|
|
214
|
-
|
|
215
|
-
function Page() {
|
|
216
|
-
const { data, refetch, status, fetchStatus } = useQuery<string>({
|
|
217
|
-
queryKey: key,
|
|
218
|
-
queryFn: async () => {
|
|
219
|
-
throw new Error('Error')
|
|
220
|
-
},
|
|
221
|
-
retry: false,
|
|
222
|
-
enabled: false,
|
|
223
|
-
throwErrors: true,
|
|
224
|
-
})
|
|
225
|
-
|
|
226
|
-
return (
|
|
227
|
-
<div>
|
|
228
|
-
<button onClick={() => refetch()}>refetch</button>
|
|
71
|
+
await waitFor(() => rendered.getByText('error boundary'))
|
|
72
|
+
await waitFor(() => rendered.getByText('retry'))
|
|
73
|
+
succeed = true
|
|
74
|
+
fireEvent.click(rendered.getByText('retry'))
|
|
75
|
+
await waitFor(() => rendered.getByText('data'))
|
|
76
|
+
consoleMock.mockRestore()
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
it('should not throw error if query is disabled', async () => {
|
|
80
|
+
const consoleMock = vi
|
|
81
|
+
.spyOn(console, 'error')
|
|
82
|
+
.mockImplementation(() => undefined)
|
|
83
|
+
const key = queryKey()
|
|
84
|
+
|
|
85
|
+
let succeed = false
|
|
86
|
+
|
|
87
|
+
function Page() {
|
|
88
|
+
const { data, status } = useQuery({
|
|
89
|
+
queryKey: key,
|
|
90
|
+
queryFn: async () => {
|
|
91
|
+
await sleep(10)
|
|
92
|
+
if (!succeed) {
|
|
93
|
+
throw new Error('Error')
|
|
94
|
+
} else {
|
|
95
|
+
return 'data'
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
retry: false,
|
|
99
|
+
enabled: !succeed,
|
|
100
|
+
throwOnError: true,
|
|
101
|
+
})
|
|
102
|
+
return (
|
|
229
103
|
<div>
|
|
230
|
-
status: {status}
|
|
104
|
+
<div>status: {status}</div>
|
|
105
|
+
<div>{data}</div>
|
|
231
106
|
</div>
|
|
232
|
-
|
|
233
|
-
|
|
107
|
+
)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const rendered = renderWithClient(
|
|
111
|
+
queryClient,
|
|
112
|
+
<QueryErrorResetBoundary>
|
|
113
|
+
{({ reset }) => (
|
|
114
|
+
<ErrorBoundary
|
|
115
|
+
onReset={reset}
|
|
116
|
+
fallbackRender={({ resetErrorBoundary }) => (
|
|
117
|
+
<div>
|
|
118
|
+
<div>error boundary</div>
|
|
119
|
+
<button
|
|
120
|
+
onClick={() => {
|
|
121
|
+
resetErrorBoundary()
|
|
122
|
+
}}
|
|
123
|
+
>
|
|
124
|
+
retry
|
|
125
|
+
</button>
|
|
126
|
+
</div>
|
|
127
|
+
)}
|
|
128
|
+
>
|
|
129
|
+
<Page />
|
|
130
|
+
</ErrorBoundary>
|
|
131
|
+
)}
|
|
132
|
+
</QueryErrorResetBoundary>,
|
|
234
133
|
)
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
const rendered = renderWithClient(
|
|
238
|
-
queryClient,
|
|
239
|
-
<QueryErrorResetBoundary>
|
|
240
|
-
{({ reset }) => (
|
|
241
|
-
<ErrorBoundary
|
|
242
|
-
onReset={reset}
|
|
243
|
-
fallbackRender={({ resetErrorBoundary }) => (
|
|
244
|
-
<div>
|
|
245
|
-
<div>error boundary</div>
|
|
246
|
-
<button
|
|
247
|
-
onClick={() => {
|
|
248
|
-
resetErrorBoundary()
|
|
249
|
-
}}
|
|
250
|
-
>
|
|
251
|
-
retry
|
|
252
|
-
</button>
|
|
253
|
-
</div>
|
|
254
|
-
)}
|
|
255
|
-
>
|
|
256
|
-
<Page />
|
|
257
|
-
</ErrorBoundary>
|
|
258
|
-
)}
|
|
259
|
-
</QueryErrorResetBoundary>,
|
|
260
|
-
)
|
|
261
|
-
|
|
262
|
-
await waitFor(() =>
|
|
263
|
-
rendered.getByText('status: pending, fetchStatus: idle'),
|
|
264
|
-
)
|
|
265
|
-
fireEvent.click(rendered.getByRole('button', { name: /refetch/i }))
|
|
266
|
-
await waitFor(() => rendered.getByText('error boundary'))
|
|
267
|
-
consoleMock.mockRestore()
|
|
268
|
-
})
|
|
269
|
-
|
|
270
|
-
it('should not retry fetch if the reset error boundary has not been reset', async () => {
|
|
271
|
-
const consoleMock = vi
|
|
272
|
-
.spyOn(console, 'error')
|
|
273
|
-
.mockImplementation(() => undefined)
|
|
274
|
-
|
|
275
|
-
const key = queryKey()
|
|
276
|
-
|
|
277
|
-
let succeed = false
|
|
278
|
-
|
|
279
|
-
function Page() {
|
|
280
|
-
const { data } = useQuery({
|
|
281
|
-
queryKey: key,
|
|
282
|
-
queryFn: async () => {
|
|
283
|
-
await sleep(10)
|
|
284
|
-
if (!succeed) {
|
|
285
|
-
throw new Error('Error')
|
|
286
|
-
} else {
|
|
287
|
-
return 'data'
|
|
288
|
-
}
|
|
289
|
-
},
|
|
290
|
-
retry: false,
|
|
291
|
-
throwErrors: true,
|
|
292
|
-
})
|
|
293
|
-
return <div>{data}</div>
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
const rendered = renderWithClient(
|
|
297
|
-
queryClient,
|
|
298
|
-
<QueryErrorResetBoundary>
|
|
299
|
-
{() => (
|
|
300
|
-
<ErrorBoundary
|
|
301
|
-
fallbackRender={({ resetErrorBoundary }) => (
|
|
302
|
-
<div>
|
|
303
|
-
<div>error boundary</div>
|
|
304
|
-
<button
|
|
305
|
-
onClick={() => {
|
|
306
|
-
resetErrorBoundary()
|
|
307
|
-
}}
|
|
308
|
-
>
|
|
309
|
-
retry
|
|
310
|
-
</button>
|
|
311
|
-
</div>
|
|
312
|
-
)}
|
|
313
|
-
>
|
|
314
|
-
<Page />
|
|
315
|
-
</ErrorBoundary>
|
|
316
|
-
)}
|
|
317
|
-
</QueryErrorResetBoundary>,
|
|
318
|
-
)
|
|
319
|
-
|
|
320
|
-
await waitFor(() => rendered.getByText('error boundary'))
|
|
321
|
-
await waitFor(() => rendered.getByText('retry'))
|
|
322
|
-
succeed = true
|
|
323
|
-
fireEvent.click(rendered.getByText('retry'))
|
|
324
|
-
await waitFor(() => rendered.getByText('error boundary'))
|
|
325
|
-
consoleMock.mockRestore()
|
|
326
|
-
})
|
|
327
|
-
|
|
328
|
-
it('should retry fetch if the reset error boundary has been reset and the query contains data from a previous fetch', async () => {
|
|
329
|
-
const consoleMock = vi
|
|
330
|
-
.spyOn(console, 'error')
|
|
331
|
-
.mockImplementation(() => undefined)
|
|
332
|
-
|
|
333
|
-
const key = queryKey()
|
|
334
134
|
|
|
335
|
-
|
|
135
|
+
await waitFor(() => rendered.getByText('error boundary'))
|
|
136
|
+
await waitFor(() => rendered.getByText('retry'))
|
|
137
|
+
succeed = true
|
|
138
|
+
fireEvent.click(rendered.getByText('retry'))
|
|
139
|
+
await waitFor(() => rendered.getByText('status: error'))
|
|
140
|
+
consoleMock.mockRestore()
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
it('should not throw error if query is disabled, and refetch if query becomes enabled again', async () => {
|
|
144
|
+
const consoleMock = vi
|
|
145
|
+
.spyOn(console, 'error')
|
|
146
|
+
.mockImplementation(() => undefined)
|
|
147
|
+
|
|
148
|
+
const key = queryKey()
|
|
149
|
+
|
|
150
|
+
let succeed = false
|
|
151
|
+
|
|
152
|
+
function Page() {
|
|
153
|
+
const [enabled, setEnabled] = React.useState(false)
|
|
154
|
+
const { data } = useQuery({
|
|
155
|
+
queryKey: key,
|
|
156
|
+
queryFn: async () => {
|
|
157
|
+
await sleep(10)
|
|
158
|
+
if (!succeed) {
|
|
159
|
+
throw new Error('Error')
|
|
160
|
+
} else {
|
|
161
|
+
return 'data'
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
retry: false,
|
|
165
|
+
enabled,
|
|
166
|
+
throwOnError: true,
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
React.useEffect(() => {
|
|
170
|
+
setEnabled(true)
|
|
171
|
+
}, [])
|
|
172
|
+
|
|
173
|
+
return <div>{data}</div>
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const rendered = renderWithClient(
|
|
177
|
+
queryClient,
|
|
178
|
+
<QueryErrorResetBoundary>
|
|
179
|
+
{({ reset }) => (
|
|
180
|
+
<ErrorBoundary
|
|
181
|
+
onReset={reset}
|
|
182
|
+
fallbackRender={({ resetErrorBoundary }) => (
|
|
183
|
+
<div>
|
|
184
|
+
<div>error boundary</div>
|
|
185
|
+
<button
|
|
186
|
+
onClick={() => {
|
|
187
|
+
resetErrorBoundary()
|
|
188
|
+
}}
|
|
189
|
+
>
|
|
190
|
+
retry
|
|
191
|
+
</button>
|
|
192
|
+
</div>
|
|
193
|
+
)}
|
|
194
|
+
>
|
|
195
|
+
<Page />
|
|
196
|
+
</ErrorBoundary>
|
|
197
|
+
)}
|
|
198
|
+
</QueryErrorResetBoundary>,
|
|
199
|
+
)
|
|
336
200
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
201
|
+
await waitFor(() => rendered.getByText('error boundary'))
|
|
202
|
+
await waitFor(() => rendered.getByText('retry'))
|
|
203
|
+
succeed = true
|
|
204
|
+
fireEvent.click(rendered.getByText('retry'))
|
|
205
|
+
await waitFor(() => rendered.getByText('data'))
|
|
206
|
+
consoleMock.mockRestore()
|
|
207
|
+
})
|
|
208
|
+
|
|
209
|
+
it('should throw error if query is disabled and manually refetched', async () => {
|
|
210
|
+
const consoleMock = vi
|
|
211
|
+
.spyOn(console, 'error')
|
|
212
|
+
.mockImplementation(() => undefined)
|
|
213
|
+
|
|
214
|
+
const key = queryKey()
|
|
215
|
+
|
|
216
|
+
function Page() {
|
|
217
|
+
const { data, refetch, status, fetchStatus } = useQuery<string>({
|
|
218
|
+
queryKey: key,
|
|
219
|
+
queryFn: async () => {
|
|
343
220
|
throw new Error('Error')
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
throwErrors: true,
|
|
350
|
-
initialData: 'initial',
|
|
351
|
-
})
|
|
352
|
-
return <div>{data}</div>
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
const rendered = renderWithClient(
|
|
356
|
-
queryClient,
|
|
357
|
-
<QueryErrorResetBoundary>
|
|
358
|
-
{({ reset }) => (
|
|
359
|
-
<ErrorBoundary
|
|
360
|
-
onReset={reset}
|
|
361
|
-
fallbackRender={({ resetErrorBoundary }) => (
|
|
362
|
-
<div>
|
|
363
|
-
<div>error boundary</div>
|
|
364
|
-
<button
|
|
365
|
-
onClick={() => {
|
|
366
|
-
resetErrorBoundary()
|
|
367
|
-
}}
|
|
368
|
-
>
|
|
369
|
-
retry
|
|
370
|
-
</button>
|
|
371
|
-
</div>
|
|
372
|
-
)}
|
|
373
|
-
>
|
|
374
|
-
<Page />
|
|
375
|
-
</ErrorBoundary>
|
|
376
|
-
)}
|
|
377
|
-
</QueryErrorResetBoundary>,
|
|
378
|
-
)
|
|
379
|
-
|
|
380
|
-
await waitFor(() => rendered.getByText('error boundary'))
|
|
381
|
-
await waitFor(() => rendered.getByText('retry'))
|
|
382
|
-
succeed = true
|
|
383
|
-
fireEvent.click(rendered.getByText('retry'))
|
|
384
|
-
await waitFor(() => rendered.getByText('data'))
|
|
385
|
-
consoleMock.mockRestore()
|
|
386
|
-
})
|
|
221
|
+
},
|
|
222
|
+
retry: false,
|
|
223
|
+
enabled: false,
|
|
224
|
+
throwOnError: true,
|
|
225
|
+
})
|
|
387
226
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
227
|
+
return (
|
|
228
|
+
<div>
|
|
229
|
+
<button onClick={() => refetch()}>refetch</button>
|
|
230
|
+
<div>
|
|
231
|
+
status: {status}, fetchStatus: {fetchStatus}
|
|
232
|
+
</div>
|
|
233
|
+
<div>{data}</div>
|
|
234
|
+
</div>
|
|
235
|
+
)
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const rendered = renderWithClient(
|
|
239
|
+
queryClient,
|
|
240
|
+
<QueryErrorResetBoundary>
|
|
241
|
+
{({ reset }) => (
|
|
242
|
+
<ErrorBoundary
|
|
243
|
+
onReset={reset}
|
|
244
|
+
fallbackRender={({ resetErrorBoundary }) => (
|
|
245
|
+
<div>
|
|
246
|
+
<div>error boundary</div>
|
|
247
|
+
<button
|
|
248
|
+
onClick={() => {
|
|
249
|
+
resetErrorBoundary()
|
|
250
|
+
}}
|
|
251
|
+
>
|
|
252
|
+
retry
|
|
253
|
+
</button>
|
|
254
|
+
</div>
|
|
255
|
+
)}
|
|
256
|
+
>
|
|
257
|
+
<Page />
|
|
258
|
+
</ErrorBoundary>
|
|
259
|
+
)}
|
|
260
|
+
</QueryErrorResetBoundary>,
|
|
261
|
+
)
|
|
394
262
|
|
|
395
|
-
|
|
396
|
-
|
|
263
|
+
await waitFor(() =>
|
|
264
|
+
rendered.getByText('status: pending, fetchStatus: idle'),
|
|
265
|
+
)
|
|
266
|
+
fireEvent.click(rendered.getByRole('button', { name: /refetch/i }))
|
|
267
|
+
await waitFor(() => rendered.getByText('error boundary'))
|
|
268
|
+
consoleMock.mockRestore()
|
|
269
|
+
})
|
|
270
|
+
|
|
271
|
+
it('should not retry fetch if the reset error boundary has not been reset', async () => {
|
|
272
|
+
const consoleMock = vi
|
|
273
|
+
.spyOn(console, 'error')
|
|
274
|
+
.mockImplementation(() => undefined)
|
|
275
|
+
|
|
276
|
+
const key = queryKey()
|
|
277
|
+
|
|
278
|
+
let succeed = false
|
|
279
|
+
|
|
280
|
+
function Page() {
|
|
281
|
+
const { data } = useQuery({
|
|
282
|
+
queryKey: key,
|
|
283
|
+
queryFn: async () => {
|
|
284
|
+
await sleep(10)
|
|
285
|
+
if (!succeed) {
|
|
286
|
+
throw new Error('Error')
|
|
287
|
+
} else {
|
|
288
|
+
return 'data'
|
|
289
|
+
}
|
|
290
|
+
},
|
|
291
|
+
retry: false,
|
|
292
|
+
throwOnError: true,
|
|
293
|
+
})
|
|
294
|
+
return <div>{data}</div>
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
const rendered = renderWithClient(
|
|
298
|
+
queryClient,
|
|
299
|
+
<QueryErrorResetBoundary>
|
|
300
|
+
{() => (
|
|
301
|
+
<ErrorBoundary
|
|
302
|
+
fallbackRender={({ resetErrorBoundary }) => (
|
|
303
|
+
<div>
|
|
304
|
+
<div>error boundary</div>
|
|
305
|
+
<button
|
|
306
|
+
onClick={() => {
|
|
307
|
+
resetErrorBoundary()
|
|
308
|
+
}}
|
|
309
|
+
>
|
|
310
|
+
retry
|
|
311
|
+
</button>
|
|
312
|
+
</div>
|
|
313
|
+
)}
|
|
314
|
+
>
|
|
315
|
+
<Page />
|
|
316
|
+
</ErrorBoundary>
|
|
317
|
+
)}
|
|
318
|
+
</QueryErrorResetBoundary>,
|
|
319
|
+
)
|
|
397
320
|
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
321
|
+
await waitFor(() => rendered.getByText('error boundary'))
|
|
322
|
+
await waitFor(() => rendered.getByText('retry'))
|
|
323
|
+
succeed = true
|
|
324
|
+
fireEvent.click(rendered.getByText('retry'))
|
|
325
|
+
await waitFor(() => rendered.getByText('error boundary'))
|
|
326
|
+
consoleMock.mockRestore()
|
|
327
|
+
})
|
|
328
|
+
|
|
329
|
+
it('should retry fetch if the reset error boundary has been reset and the query contains data from a previous fetch', async () => {
|
|
330
|
+
const consoleMock = vi
|
|
331
|
+
.spyOn(console, 'error')
|
|
332
|
+
.mockImplementation(() => undefined)
|
|
333
|
+
|
|
334
|
+
const key = queryKey()
|
|
335
|
+
|
|
336
|
+
let succeed = false
|
|
337
|
+
|
|
338
|
+
function Page() {
|
|
339
|
+
const { data } = useQuery({
|
|
340
|
+
queryKey: key,
|
|
341
|
+
queryFn: async () => {
|
|
342
|
+
await sleep(10)
|
|
343
|
+
if (!succeed) {
|
|
344
|
+
throw new Error('Error')
|
|
345
|
+
} else {
|
|
346
|
+
return 'data'
|
|
347
|
+
}
|
|
348
|
+
},
|
|
349
|
+
retry: false,
|
|
350
|
+
throwOnError: true,
|
|
351
|
+
initialData: 'initial',
|
|
352
|
+
})
|
|
353
|
+
return <div>{data}</div>
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
const rendered = renderWithClient(
|
|
357
|
+
queryClient,
|
|
358
|
+
<QueryErrorResetBoundary>
|
|
359
|
+
{({ reset }) => (
|
|
360
|
+
<ErrorBoundary
|
|
361
|
+
onReset={reset}
|
|
362
|
+
fallbackRender={({ resetErrorBoundary }) => (
|
|
363
|
+
<div>
|
|
364
|
+
<div>error boundary</div>
|
|
365
|
+
<button
|
|
366
|
+
onClick={() => {
|
|
367
|
+
resetErrorBoundary()
|
|
368
|
+
}}
|
|
369
|
+
>
|
|
370
|
+
retry
|
|
371
|
+
</button>
|
|
372
|
+
</div>
|
|
373
|
+
)}
|
|
374
|
+
>
|
|
375
|
+
<Page />
|
|
376
|
+
</ErrorBoundary>
|
|
377
|
+
)}
|
|
378
|
+
</QueryErrorResetBoundary>,
|
|
379
|
+
)
|
|
455
380
|
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
.
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
const
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
381
|
+
await waitFor(() => rendered.getByText('error boundary'))
|
|
382
|
+
await waitFor(() => rendered.getByText('retry'))
|
|
383
|
+
succeed = true
|
|
384
|
+
fireEvent.click(rendered.getByText('retry'))
|
|
385
|
+
await waitFor(() => rendered.getByText('data'))
|
|
386
|
+
consoleMock.mockRestore()
|
|
387
|
+
})
|
|
388
|
+
|
|
389
|
+
it('should not retry fetch if the reset error boundary has not been reset after a previous reset', async () => {
|
|
390
|
+
const consoleMock = vi
|
|
391
|
+
.spyOn(console, 'error')
|
|
392
|
+
.mockImplementation(() => undefined)
|
|
393
|
+
|
|
394
|
+
const key = queryKey()
|
|
395
|
+
|
|
396
|
+
let succeed = false
|
|
397
|
+
let shouldReset = true
|
|
398
|
+
|
|
399
|
+
function Page() {
|
|
400
|
+
const { data } = useQuery({
|
|
401
|
+
queryKey: key,
|
|
402
|
+
queryFn: async () => {
|
|
403
|
+
await sleep(10)
|
|
404
|
+
if (!succeed) {
|
|
405
|
+
throw new Error('Error')
|
|
406
|
+
} else {
|
|
407
|
+
return 'data'
|
|
408
|
+
}
|
|
409
|
+
},
|
|
410
|
+
retry: false,
|
|
411
|
+
throwOnError: true,
|
|
412
|
+
})
|
|
413
|
+
return <div>{data}</div>
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
const rendered = renderWithClient(
|
|
417
|
+
queryClient,
|
|
418
|
+
<QueryErrorResetBoundary>
|
|
419
|
+
{({ reset }) => (
|
|
420
|
+
<ErrorBoundary
|
|
421
|
+
onReset={() => {
|
|
422
|
+
if (shouldReset) {
|
|
423
|
+
reset()
|
|
424
|
+
}
|
|
425
|
+
}}
|
|
426
|
+
fallbackRender={({ resetErrorBoundary }) => (
|
|
427
|
+
<div>
|
|
428
|
+
<div>error boundary</div>
|
|
429
|
+
<button
|
|
430
|
+
onClick={() => {
|
|
431
|
+
resetErrorBoundary()
|
|
432
|
+
}}
|
|
433
|
+
>
|
|
434
|
+
retry
|
|
435
|
+
</button>
|
|
436
|
+
</div>
|
|
437
|
+
)}
|
|
438
|
+
>
|
|
439
|
+
<Page />
|
|
440
|
+
</ErrorBoundary>
|
|
441
|
+
)}
|
|
442
|
+
</QueryErrorResetBoundary>,
|
|
443
|
+
)
|
|
513
444
|
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
.
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
445
|
+
await waitFor(() => rendered.getByText('error boundary'))
|
|
446
|
+
await waitFor(() => rendered.getByText('retry'))
|
|
447
|
+
shouldReset = true
|
|
448
|
+
fireEvent.click(rendered.getByText('retry'))
|
|
449
|
+
await waitFor(() => rendered.getByText('error boundary'))
|
|
450
|
+
succeed = true
|
|
451
|
+
shouldReset = false
|
|
452
|
+
fireEvent.click(rendered.getByText('retry'))
|
|
453
|
+
await waitFor(() => rendered.getByText('error boundary'))
|
|
454
|
+
consoleMock.mockRestore()
|
|
455
|
+
})
|
|
456
|
+
|
|
457
|
+
it('should throw again on error after the reset error boundary has been reset', async () => {
|
|
458
|
+
const consoleMock = vi
|
|
459
|
+
.spyOn(console, 'error')
|
|
460
|
+
.mockImplementation(() => undefined)
|
|
461
|
+
|
|
462
|
+
const key = queryKey()
|
|
463
|
+
let fetchCount = 0
|
|
464
|
+
|
|
465
|
+
function Page() {
|
|
466
|
+
const { data } = useQuery<string>({
|
|
467
|
+
queryKey: key,
|
|
468
|
+
queryFn: async () => {
|
|
469
|
+
fetchCount++
|
|
470
|
+
await sleep(10)
|
|
532
471
|
throw new Error('Error')
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
)}
|
|
560
|
-
>
|
|
561
|
-
<React.Suspense fallback={<div>loading</div>}>
|
|
472
|
+
},
|
|
473
|
+
retry: false,
|
|
474
|
+
throwOnError: true,
|
|
475
|
+
})
|
|
476
|
+
return <div>{data}</div>
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
const rendered = renderWithClient(
|
|
480
|
+
queryClient,
|
|
481
|
+
<QueryErrorResetBoundary>
|
|
482
|
+
{({ reset }) => (
|
|
483
|
+
<ErrorBoundary
|
|
484
|
+
onReset={reset}
|
|
485
|
+
fallbackRender={({ resetErrorBoundary }) => (
|
|
486
|
+
<div>
|
|
487
|
+
<div>error boundary</div>
|
|
488
|
+
<button
|
|
489
|
+
onClick={() => {
|
|
490
|
+
resetErrorBoundary()
|
|
491
|
+
}}
|
|
492
|
+
>
|
|
493
|
+
retry
|
|
494
|
+
</button>
|
|
495
|
+
</div>
|
|
496
|
+
)}
|
|
497
|
+
>
|
|
562
498
|
<Page />
|
|
563
|
-
</
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
)
|
|
568
|
-
|
|
569
|
-
await waitFor(() => rendered.getByText('error boundary'))
|
|
570
|
-
await waitFor(() => rendered.getByText('retry'))
|
|
571
|
-
fireEvent.click(rendered.getByText('retry'))
|
|
572
|
-
await waitFor(() => rendered.getByText('error boundary'))
|
|
573
|
-
await waitFor(() => rendered.getByText('retry'))
|
|
574
|
-
fireEvent.click(rendered.getByText('retry'))
|
|
575
|
-
await waitFor(() => rendered.getByText('data'))
|
|
576
|
-
expect(fetchCount).toBe(3)
|
|
577
|
-
expect(renders).toBe(1)
|
|
578
|
-
consoleMock.mockRestore()
|
|
579
|
-
})
|
|
499
|
+
</ErrorBoundary>
|
|
500
|
+
)}
|
|
501
|
+
</QueryErrorResetBoundary>,
|
|
502
|
+
)
|
|
580
503
|
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
.
|
|
584
|
-
|
|
504
|
+
await waitFor(() => rendered.getByText('error boundary'))
|
|
505
|
+
await waitFor(() => rendered.getByText('retry'))
|
|
506
|
+
fireEvent.click(rendered.getByText('retry'))
|
|
507
|
+
await waitFor(() => rendered.getByText('error boundary'))
|
|
508
|
+
await waitFor(() => rendered.getByText('retry'))
|
|
509
|
+
fireEvent.click(rendered.getByText('retry'))
|
|
510
|
+
await waitFor(() => rendered.getByText('error boundary'))
|
|
511
|
+
expect(fetchCount).toBe(3)
|
|
512
|
+
consoleMock.mockRestore()
|
|
513
|
+
})
|
|
514
|
+
|
|
515
|
+
it('should never render the component while the query is in error state', async () => {
|
|
516
|
+
const consoleMock = vi
|
|
517
|
+
.spyOn(console, 'error')
|
|
518
|
+
.mockImplementation(() => undefined)
|
|
519
|
+
|
|
520
|
+
const key = queryKey()
|
|
521
|
+
let fetchCount = 0
|
|
522
|
+
let renders = 0
|
|
523
|
+
|
|
524
|
+
function Page() {
|
|
525
|
+
const { data } = useQuery({
|
|
526
|
+
queryKey: key,
|
|
527
|
+
queryFn: async () => {
|
|
528
|
+
fetchCount++
|
|
529
|
+
await sleep(10)
|
|
530
|
+
if (fetchCount > 2) {
|
|
531
|
+
return 'data'
|
|
532
|
+
} else {
|
|
533
|
+
throw new Error('Error')
|
|
534
|
+
}
|
|
535
|
+
},
|
|
536
|
+
retry: false,
|
|
537
|
+
suspense: true,
|
|
538
|
+
})
|
|
539
|
+
renders++
|
|
540
|
+
return <div>{data}</div>
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
const rendered = renderWithClient(
|
|
544
|
+
queryClient,
|
|
545
|
+
<QueryErrorResetBoundary>
|
|
546
|
+
{({ reset }) => (
|
|
547
|
+
<ErrorBoundary
|
|
548
|
+
onReset={reset}
|
|
549
|
+
fallbackRender={({ resetErrorBoundary }) => (
|
|
550
|
+
<div>
|
|
551
|
+
<div>error boundary</div>
|
|
552
|
+
<button
|
|
553
|
+
onClick={() => {
|
|
554
|
+
resetErrorBoundary()
|
|
555
|
+
}}
|
|
556
|
+
>
|
|
557
|
+
retry
|
|
558
|
+
</button>
|
|
559
|
+
</div>
|
|
560
|
+
)}
|
|
561
|
+
>
|
|
562
|
+
<React.Suspense fallback={<div>loading</div>}>
|
|
563
|
+
<Page />
|
|
564
|
+
</React.Suspense>
|
|
565
|
+
</ErrorBoundary>
|
|
566
|
+
)}
|
|
567
|
+
</QueryErrorResetBoundary>,
|
|
568
|
+
)
|
|
585
569
|
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
570
|
+
await waitFor(() => rendered.getByText('error boundary'))
|
|
571
|
+
await waitFor(() => rendered.getByText('retry'))
|
|
572
|
+
fireEvent.click(rendered.getByText('retry'))
|
|
573
|
+
await waitFor(() => rendered.getByText('error boundary'))
|
|
574
|
+
await waitFor(() => rendered.getByText('retry'))
|
|
575
|
+
fireEvent.click(rendered.getByText('retry'))
|
|
576
|
+
await waitFor(() => rendered.getByText('data'))
|
|
577
|
+
expect(fetchCount).toBe(3)
|
|
578
|
+
expect(renders).toBe(1)
|
|
579
|
+
consoleMock.mockRestore()
|
|
580
|
+
})
|
|
581
|
+
|
|
582
|
+
it('should render children', async () => {
|
|
583
|
+
const consoleMock = vi
|
|
584
|
+
.spyOn(console, 'error')
|
|
585
|
+
.mockImplementation(() => undefined)
|
|
586
|
+
|
|
587
|
+
function Page() {
|
|
588
|
+
return (
|
|
589
|
+
<div>
|
|
590
|
+
<span>page</span>
|
|
591
|
+
</div>
|
|
592
|
+
)
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
const rendered = renderWithClient(
|
|
596
|
+
queryClient,
|
|
597
|
+
<QueryErrorResetBoundary>
|
|
598
|
+
<Page />
|
|
599
|
+
</QueryErrorResetBoundary>,
|
|
591
600
|
)
|
|
592
|
-
}
|
|
593
601
|
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
602
|
+
expect(rendered.queryByText('page')).not.toBeNull()
|
|
603
|
+
consoleMock.mockRestore()
|
|
604
|
+
})
|
|
605
|
+
|
|
606
|
+
it('should show error boundary when using tracked queries even though we do not track the error field', async () => {
|
|
607
|
+
const consoleMock = vi
|
|
608
|
+
.spyOn(console, 'error')
|
|
609
|
+
.mockImplementation(() => undefined)
|
|
610
|
+
|
|
611
|
+
const key = queryKey()
|
|
612
|
+
|
|
613
|
+
let succeed = false
|
|
614
|
+
|
|
615
|
+
function Page() {
|
|
616
|
+
const { data } = useQuery({
|
|
617
|
+
queryKey: key,
|
|
618
|
+
queryFn: async () => {
|
|
619
|
+
await sleep(10)
|
|
620
|
+
if (!succeed) {
|
|
621
|
+
throw new Error('Error')
|
|
622
|
+
} else {
|
|
623
|
+
return 'data'
|
|
624
|
+
}
|
|
625
|
+
},
|
|
626
|
+
retry: false,
|
|
627
|
+
throwOnError: true,
|
|
628
|
+
})
|
|
629
|
+
return <div>{data}</div>
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
const rendered = renderWithClient(
|
|
633
|
+
queryClient,
|
|
634
|
+
<QueryErrorResetBoundary>
|
|
635
|
+
{({ reset }) => (
|
|
636
|
+
<ErrorBoundary
|
|
637
|
+
onReset={reset}
|
|
638
|
+
fallbackRender={({ resetErrorBoundary }) => (
|
|
639
|
+
<div>
|
|
640
|
+
<div>error boundary</div>
|
|
641
|
+
<button
|
|
642
|
+
onClick={() => {
|
|
643
|
+
resetErrorBoundary()
|
|
644
|
+
}}
|
|
645
|
+
>
|
|
646
|
+
retry
|
|
647
|
+
</button>
|
|
648
|
+
</div>
|
|
649
|
+
)}
|
|
650
|
+
>
|
|
651
|
+
<Page />
|
|
652
|
+
</ErrorBoundary>
|
|
653
|
+
)}
|
|
654
|
+
</QueryErrorResetBoundary>,
|
|
655
|
+
)
|
|
600
656
|
|
|
601
|
-
|
|
602
|
-
|
|
657
|
+
await waitFor(() => rendered.getByText('error boundary'))
|
|
658
|
+
await waitFor(() => rendered.getByText('retry'))
|
|
659
|
+
succeed = true
|
|
660
|
+
fireEvent.click(rendered.getByText('retry'))
|
|
661
|
+
await waitFor(() => rendered.getByText('data'))
|
|
662
|
+
consoleMock.mockRestore()
|
|
663
|
+
})
|
|
603
664
|
})
|
|
665
|
+
describe('useQueries', () => {
|
|
666
|
+
it('should retry fetch if the reset error boundary has been reset', async () => {
|
|
667
|
+
const consoleMock = vi
|
|
668
|
+
.spyOn(console, 'error')
|
|
669
|
+
.mockImplementation(() => undefined)
|
|
670
|
+
const key = queryKey()
|
|
671
|
+
|
|
672
|
+
let succeed = false
|
|
673
|
+
|
|
674
|
+
function Page() {
|
|
675
|
+
const [{ data }] = useQueries({
|
|
676
|
+
queries: [
|
|
677
|
+
{
|
|
678
|
+
queryKey: key,
|
|
679
|
+
queryFn: async () => {
|
|
680
|
+
await sleep(10)
|
|
681
|
+
if (!succeed) {
|
|
682
|
+
throw new Error('Error')
|
|
683
|
+
} else {
|
|
684
|
+
return 'data'
|
|
685
|
+
}
|
|
686
|
+
},
|
|
687
|
+
retry: false,
|
|
688
|
+
throwOnError: true,
|
|
689
|
+
retryOnMount: true,
|
|
690
|
+
},
|
|
691
|
+
],
|
|
692
|
+
})
|
|
693
|
+
return <div>{data}</div>
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
const rendered = renderWithClient(
|
|
697
|
+
queryClient,
|
|
698
|
+
<QueryErrorResetBoundary>
|
|
699
|
+
{({ reset }) => (
|
|
700
|
+
<ErrorBoundary
|
|
701
|
+
onReset={reset}
|
|
702
|
+
fallbackRender={({ resetErrorBoundary }) => (
|
|
703
|
+
<div>
|
|
704
|
+
<div>error boundary</div>
|
|
705
|
+
<button
|
|
706
|
+
onClick={() => {
|
|
707
|
+
resetErrorBoundary()
|
|
708
|
+
}}
|
|
709
|
+
>
|
|
710
|
+
retry
|
|
711
|
+
</button>
|
|
712
|
+
</div>
|
|
713
|
+
)}
|
|
714
|
+
>
|
|
715
|
+
<Page />
|
|
716
|
+
</ErrorBoundary>
|
|
717
|
+
)}
|
|
718
|
+
</QueryErrorResetBoundary>,
|
|
719
|
+
)
|
|
604
720
|
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
.
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
721
|
+
await waitFor(() => rendered.getByText('error boundary'))
|
|
722
|
+
await waitFor(() => rendered.getByText('retry'))
|
|
723
|
+
succeed = true
|
|
724
|
+
fireEvent.click(rendered.getByText('retry'))
|
|
725
|
+
await waitFor(() => rendered.getByText('data'))
|
|
726
|
+
consoleMock.mockRestore()
|
|
727
|
+
})
|
|
728
|
+
|
|
729
|
+
it('with suspense should retry fetch if the reset error boundary has been reset', async () => {
|
|
730
|
+
const key = queryKey()
|
|
731
|
+
const consoleMock = vi
|
|
732
|
+
.spyOn(console, 'error')
|
|
733
|
+
.mockImplementation(() => undefined)
|
|
734
|
+
|
|
735
|
+
let succeed = false
|
|
736
|
+
|
|
737
|
+
function Page() {
|
|
738
|
+
const [{ data }] = useQueries({
|
|
739
|
+
queries: [
|
|
740
|
+
{
|
|
741
|
+
queryKey: key,
|
|
742
|
+
queryFn: async () => {
|
|
743
|
+
await sleep(10)
|
|
744
|
+
if (!succeed) {
|
|
745
|
+
throw new Error('Error')
|
|
746
|
+
} else {
|
|
747
|
+
return 'data'
|
|
748
|
+
}
|
|
749
|
+
},
|
|
750
|
+
retry: false,
|
|
751
|
+
throwOnError: true,
|
|
752
|
+
retryOnMount: true,
|
|
753
|
+
suspense: true,
|
|
754
|
+
},
|
|
755
|
+
],
|
|
756
|
+
})
|
|
757
|
+
return <div>{data}</div>
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
const rendered = renderWithClient(
|
|
761
|
+
queryClient,
|
|
762
|
+
<QueryErrorResetBoundary>
|
|
763
|
+
{({ reset }) => (
|
|
764
|
+
<ErrorBoundary
|
|
765
|
+
onReset={reset}
|
|
766
|
+
fallbackRender={({ resetErrorBoundary }) => (
|
|
767
|
+
<div>
|
|
768
|
+
<div>error boundary</div>
|
|
769
|
+
<button
|
|
770
|
+
onClick={() => {
|
|
771
|
+
resetErrorBoundary()
|
|
772
|
+
}}
|
|
773
|
+
>
|
|
774
|
+
retry
|
|
775
|
+
</button>
|
|
776
|
+
</div>
|
|
777
|
+
)}
|
|
778
|
+
>
|
|
779
|
+
<React.Suspense fallback="Loader">
|
|
780
|
+
<Page />
|
|
781
|
+
</React.Suspense>
|
|
782
|
+
</ErrorBoundary>
|
|
783
|
+
)}
|
|
784
|
+
</QueryErrorResetBoundary>,
|
|
785
|
+
)
|
|
613
786
|
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
} else {
|
|
622
|
-
return 'data'
|
|
623
|
-
}
|
|
624
|
-
},
|
|
625
|
-
retry: false,
|
|
626
|
-
throwErrors: true,
|
|
627
|
-
})
|
|
628
|
-
return <div>{data}</div>
|
|
629
|
-
}
|
|
630
|
-
|
|
631
|
-
const rendered = renderWithClient(
|
|
632
|
-
queryClient,
|
|
633
|
-
<QueryErrorResetBoundary>
|
|
634
|
-
{({ reset }) => (
|
|
635
|
-
<ErrorBoundary
|
|
636
|
-
onReset={reset}
|
|
637
|
-
fallbackRender={({ resetErrorBoundary }) => (
|
|
638
|
-
<div>
|
|
639
|
-
<div>error boundary</div>
|
|
640
|
-
<button
|
|
641
|
-
onClick={() => {
|
|
642
|
-
resetErrorBoundary()
|
|
643
|
-
}}
|
|
644
|
-
>
|
|
645
|
-
retry
|
|
646
|
-
</button>
|
|
647
|
-
</div>
|
|
648
|
-
)}
|
|
649
|
-
>
|
|
650
|
-
<Page />
|
|
651
|
-
</ErrorBoundary>
|
|
652
|
-
)}
|
|
653
|
-
</QueryErrorResetBoundary>,
|
|
654
|
-
)
|
|
655
|
-
|
|
656
|
-
await waitFor(() => rendered.getByText('error boundary'))
|
|
657
|
-
await waitFor(() => rendered.getByText('retry'))
|
|
658
|
-
succeed = true
|
|
659
|
-
fireEvent.click(rendered.getByText('retry'))
|
|
660
|
-
await waitFor(() => rendered.getByText('data'))
|
|
661
|
-
consoleMock.mockRestore()
|
|
787
|
+
await waitFor(() => rendered.getByText('error boundary'))
|
|
788
|
+
await waitFor(() => rendered.getByText('retry'))
|
|
789
|
+
succeed = true
|
|
790
|
+
fireEvent.click(rendered.getByText('retry'))
|
|
791
|
+
await waitFor(() => rendered.getByText('data'))
|
|
792
|
+
consoleMock.mockRestore()
|
|
793
|
+
})
|
|
662
794
|
})
|
|
663
795
|
})
|