Skip to content

Commit 41ea6d9

Browse files
committed
feat: switch to use instead of throwing promises
1 parent f8031f4 commit 41ea6d9

3 files changed

Lines changed: 44 additions & 3 deletions

File tree

packages/react-query/src/suspense.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import * as React from 'react'
12
import type { DefaultError } from '@tanstack/query-core'
23
import type {
34
DefaultedQueryObserverOptions,
@@ -30,6 +31,40 @@ export const ensureStaleTime = (
3031
}
3132
}
3233

34+
export const use =
35+
// React18 doesn't have `use`
36+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
37+
React.use ||
38+
(<T>(
39+
thenable: Promise<T> & {
40+
status?: 'pending' | 'fulfilled' | 'rejected'
41+
value?: T
42+
reason?: unknown
43+
},
44+
): T => {
45+
switch (thenable.status) {
46+
case 'pending':
47+
throw thenable
48+
case 'fulfilled':
49+
return thenable.value as T
50+
case 'rejected':
51+
throw thenable.reason
52+
default:
53+
thenable.status = 'pending'
54+
thenable.then(
55+
(v) => {
56+
thenable.status = 'fulfilled'
57+
thenable.value = v
58+
},
59+
(e) => {
60+
thenable.status = 'rejected'
61+
thenable.reason = e
62+
},
63+
)
64+
throw thenable
65+
}
66+
})
67+
3368
export const willFetch = (
3469
result: QueryObserverResult<any, any>,
3570
isRestoring: boolean,

packages/react-query/src/useBaseQuery.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,12 @@ import {
1010
getHasError,
1111
useClearResetErrorBoundary,
1212
} from './errorBoundaryUtils'
13-
import { ensureStaleTime, fetchOptimistic, shouldSuspend } from './suspense'
13+
import {
14+
ensureStaleTime,
15+
fetchOptimistic,
16+
shouldSuspend,
17+
use,
18+
} from './suspense'
1419
import type { UseBaseQueryOptions } from './types'
1520
import type {
1621
QueryClient,
@@ -99,7 +104,7 @@ export function useBaseQuery<
99104
// Do the same thing as the effect right above because the effect won't run
100105
// when we suspend but also, the component won't re-mount so our observer would
101106
// be out of date.
102-
throw fetchOptimistic(defaultedOptions, observer, errorResetBoundary)
107+
use(fetchOptimistic(defaultedOptions, observer, errorResetBoundary))
103108
}
104109

105110
// Handle error boundary

packages/react-query/src/useQueries.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
ensureStaleTime,
1919
fetchOptimistic,
2020
shouldSuspend,
21+
use,
2122
willFetch,
2223
} from './suspense'
2324
import type {
@@ -346,7 +347,7 @@ export function useQueries<
346347
: []
347348

348349
if (suspensePromises.length > 0) {
349-
throw Promise.all(suspensePromises)
350+
use(Promise.all(suspensePromises))
350351
}
351352
const firstSingleResultWhichShouldThrow = optimisticResult.find(
352353
(result, index) => {

0 commit comments

Comments
 (0)