@tanstack/preact-query 5.102.8 → 5.103.1
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/HydrationBoundary.cjs +1 -1
- package/build/legacy/HydrationBoundary.cjs.map +1 -1
- package/build/legacy/HydrationBoundary.js +1 -1
- package/build/legacy/HydrationBoundary.js.map +1 -1
- package/build/legacy/QueryErrorResetBoundary.cjs +12 -12
- package/build/legacy/QueryErrorResetBoundary.cjs.map +1 -1
- package/build/legacy/QueryErrorResetBoundary.d.cts +12 -12
- package/build/legacy/QueryErrorResetBoundary.d.ts +12 -12
- package/build/legacy/QueryErrorResetBoundary.js +12 -12
- package/build/legacy/QueryErrorResetBoundary.js.map +1 -1
- package/build/legacy/infiniteQueryOptions.cjs.map +1 -1
- package/build/legacy/infiniteQueryOptions.d.cts +41 -55
- package/build/legacy/infiniteQueryOptions.d.cts.map +1 -1
- package/build/legacy/infiniteQueryOptions.d.ts +41 -55
- package/build/legacy/infiniteQueryOptions.d.ts.map +1 -1
- package/build/legacy/infiniteQueryOptions.js.map +1 -1
- package/build/legacy/mutationOptions.cjs.map +1 -1
- package/build/legacy/mutationOptions.d.cts +4 -17
- package/build/legacy/mutationOptions.d.cts.map +1 -1
- package/build/legacy/mutationOptions.d.ts +4 -17
- package/build/legacy/mutationOptions.d.ts.map +1 -1
- package/build/legacy/mutationOptions.js.map +1 -1
- package/build/legacy/queryOptions.cjs.map +1 -1
- package/build/legacy/queryOptions.d.cts +51 -74
- package/build/legacy/queryOptions.d.cts.map +1 -1
- package/build/legacy/queryOptions.d.ts +51 -74
- package/build/legacy/queryOptions.d.ts.map +1 -1
- package/build/legacy/queryOptions.js.map +1 -1
- package/build/legacy/useInfiniteQuery.cjs.map +1 -1
- package/build/legacy/useInfiniteQuery.d.cts +208 -36
- package/build/legacy/useInfiniteQuery.d.cts.map +1 -1
- package/build/legacy/useInfiniteQuery.d.ts +208 -36
- package/build/legacy/useInfiniteQuery.d.ts.map +1 -1
- package/build/legacy/useInfiniteQuery.js.map +1 -1
- package/build/legacy/useIsFetching.cjs +8 -6
- package/build/legacy/useIsFetching.cjs.map +1 -1
- package/build/legacy/useIsFetching.d.cts +8 -6
- package/build/legacy/useIsFetching.d.cts.map +1 -1
- package/build/legacy/useIsFetching.d.ts +8 -6
- package/build/legacy/useIsFetching.d.ts.map +1 -1
- package/build/legacy/useIsFetching.js +8 -6
- package/build/legacy/useIsFetching.js.map +1 -1
- package/build/legacy/useMutation.cjs +13 -11
- package/build/legacy/useMutation.cjs.map +1 -1
- package/build/legacy/useMutation.d.cts +13 -11
- package/build/legacy/useMutation.d.cts.map +1 -1
- package/build/legacy/useMutation.d.ts +13 -11
- package/build/legacy/useMutation.d.ts.map +1 -1
- package/build/legacy/useMutation.js +13 -11
- package/build/legacy/useMutation.js.map +1 -1
- package/build/legacy/useMutationState.cjs +49 -29
- package/build/legacy/useMutationState.cjs.map +1 -1
- package/build/legacy/useMutationState.d.cts +49 -29
- package/build/legacy/useMutationState.d.cts.map +1 -1
- package/build/legacy/useMutationState.d.ts +49 -29
- package/build/legacy/useMutationState.d.ts.map +1 -1
- package/build/legacy/useMutationState.js +49 -29
- package/build/legacy/useMutationState.js.map +1 -1
- package/build/legacy/useQueries.cjs +50 -23
- package/build/legacy/useQueries.cjs.map +1 -1
- package/build/legacy/useQueries.d.cts +50 -23
- package/build/legacy/useQueries.d.cts.map +1 -1
- package/build/legacy/useQueries.d.ts +50 -23
- package/build/legacy/useQueries.d.ts.map +1 -1
- package/build/legacy/useQueries.js +50 -23
- package/build/legacy/useQueries.js.map +1 -1
- package/build/legacy/useQuery.cjs.map +1 -1
- package/build/legacy/useQuery.d.cts +93 -33
- package/build/legacy/useQuery.d.cts.map +1 -1
- package/build/legacy/useQuery.d.ts +93 -33
- package/build/legacy/useQuery.d.ts.map +1 -1
- package/build/legacy/useQuery.js.map +1 -1
- package/build/legacy/useSuspenseInfiniteQuery.cjs +57 -7
- package/build/legacy/useSuspenseInfiniteQuery.cjs.map +1 -1
- package/build/legacy/useSuspenseInfiniteQuery.d.cts +57 -7
- package/build/legacy/useSuspenseInfiniteQuery.d.cts.map +1 -1
- package/build/legacy/useSuspenseInfiniteQuery.d.ts +57 -7
- package/build/legacy/useSuspenseInfiniteQuery.d.ts.map +1 -1
- package/build/legacy/useSuspenseInfiniteQuery.js +57 -7
- package/build/legacy/useSuspenseInfiniteQuery.js.map +1 -1
- package/build/legacy/useSuspenseQueries.cjs.map +1 -1
- package/build/legacy/useSuspenseQueries.d.cts +244 -20
- package/build/legacy/useSuspenseQueries.d.cts.map +1 -1
- package/build/legacy/useSuspenseQueries.d.ts +244 -20
- package/build/legacy/useSuspenseQueries.d.ts.map +1 -1
- package/build/legacy/useSuspenseQueries.js.map +1 -1
- package/build/legacy/useSuspenseQuery.cjs +48 -8
- package/build/legacy/useSuspenseQuery.cjs.map +1 -1
- package/build/legacy/useSuspenseQuery.d.cts +48 -8
- package/build/legacy/useSuspenseQuery.d.cts.map +1 -1
- package/build/legacy/useSuspenseQuery.d.ts +48 -8
- package/build/legacy/useSuspenseQuery.d.ts.map +1 -1
- package/build/legacy/useSuspenseQuery.js +48 -8
- package/build/legacy/useSuspenseQuery.js.map +1 -1
- package/build/modern/HydrationBoundary.cjs +1 -1
- package/build/modern/HydrationBoundary.cjs.map +1 -1
- package/build/modern/HydrationBoundary.js +1 -1
- package/build/modern/HydrationBoundary.js.map +1 -1
- package/build/modern/QueryErrorResetBoundary.cjs +12 -12
- package/build/modern/QueryErrorResetBoundary.cjs.map +1 -1
- package/build/modern/QueryErrorResetBoundary.d.cts +12 -12
- package/build/modern/QueryErrorResetBoundary.d.ts +12 -12
- package/build/modern/QueryErrorResetBoundary.js +12 -12
- package/build/modern/QueryErrorResetBoundary.js.map +1 -1
- package/build/modern/infiniteQueryOptions.cjs.map +1 -1
- package/build/modern/infiniteQueryOptions.d.cts +41 -55
- package/build/modern/infiniteQueryOptions.d.cts.map +1 -1
- package/build/modern/infiniteQueryOptions.d.ts +41 -55
- package/build/modern/infiniteQueryOptions.d.ts.map +1 -1
- package/build/modern/infiniteQueryOptions.js.map +1 -1
- package/build/modern/mutationOptions.cjs.map +1 -1
- package/build/modern/mutationOptions.d.cts +4 -17
- package/build/modern/mutationOptions.d.cts.map +1 -1
- package/build/modern/mutationOptions.d.ts +4 -17
- package/build/modern/mutationOptions.d.ts.map +1 -1
- package/build/modern/mutationOptions.js.map +1 -1
- package/build/modern/queryOptions.cjs.map +1 -1
- package/build/modern/queryOptions.d.cts +51 -74
- package/build/modern/queryOptions.d.cts.map +1 -1
- package/build/modern/queryOptions.d.ts +51 -74
- package/build/modern/queryOptions.d.ts.map +1 -1
- package/build/modern/queryOptions.js.map +1 -1
- package/build/modern/useInfiniteQuery.cjs.map +1 -1
- package/build/modern/useInfiniteQuery.d.cts +208 -36
- package/build/modern/useInfiniteQuery.d.cts.map +1 -1
- package/build/modern/useInfiniteQuery.d.ts +208 -36
- package/build/modern/useInfiniteQuery.d.ts.map +1 -1
- package/build/modern/useInfiniteQuery.js.map +1 -1
- package/build/modern/useIsFetching.cjs +8 -6
- package/build/modern/useIsFetching.cjs.map +1 -1
- package/build/modern/useIsFetching.d.cts +8 -6
- package/build/modern/useIsFetching.d.cts.map +1 -1
- package/build/modern/useIsFetching.d.ts +8 -6
- package/build/modern/useIsFetching.d.ts.map +1 -1
- package/build/modern/useIsFetching.js +8 -6
- package/build/modern/useIsFetching.js.map +1 -1
- package/build/modern/useMutation.cjs +13 -11
- package/build/modern/useMutation.cjs.map +1 -1
- package/build/modern/useMutation.d.cts +13 -11
- package/build/modern/useMutation.d.cts.map +1 -1
- package/build/modern/useMutation.d.ts +13 -11
- package/build/modern/useMutation.d.ts.map +1 -1
- package/build/modern/useMutation.js +13 -11
- package/build/modern/useMutation.js.map +1 -1
- package/build/modern/useMutationState.cjs +49 -29
- package/build/modern/useMutationState.cjs.map +1 -1
- package/build/modern/useMutationState.d.cts +49 -29
- package/build/modern/useMutationState.d.cts.map +1 -1
- package/build/modern/useMutationState.d.ts +49 -29
- package/build/modern/useMutationState.d.ts.map +1 -1
- package/build/modern/useMutationState.js +49 -29
- package/build/modern/useMutationState.js.map +1 -1
- package/build/modern/useQueries.cjs +50 -23
- package/build/modern/useQueries.cjs.map +1 -1
- package/build/modern/useQueries.d.cts +50 -23
- package/build/modern/useQueries.d.cts.map +1 -1
- package/build/modern/useQueries.d.ts +50 -23
- package/build/modern/useQueries.d.ts.map +1 -1
- package/build/modern/useQueries.js +50 -23
- package/build/modern/useQueries.js.map +1 -1
- package/build/modern/useQuery.cjs.map +1 -1
- package/build/modern/useQuery.d.cts +93 -33
- package/build/modern/useQuery.d.cts.map +1 -1
- package/build/modern/useQuery.d.ts +93 -33
- package/build/modern/useQuery.d.ts.map +1 -1
- package/build/modern/useQuery.js.map +1 -1
- package/build/modern/useSuspenseInfiniteQuery.cjs +57 -7
- package/build/modern/useSuspenseInfiniteQuery.cjs.map +1 -1
- package/build/modern/useSuspenseInfiniteQuery.d.cts +57 -7
- package/build/modern/useSuspenseInfiniteQuery.d.cts.map +1 -1
- package/build/modern/useSuspenseInfiniteQuery.d.ts +57 -7
- package/build/modern/useSuspenseInfiniteQuery.d.ts.map +1 -1
- package/build/modern/useSuspenseInfiniteQuery.js +57 -7
- package/build/modern/useSuspenseInfiniteQuery.js.map +1 -1
- package/build/modern/useSuspenseQueries.cjs.map +1 -1
- package/build/modern/useSuspenseQueries.d.cts +244 -20
- package/build/modern/useSuspenseQueries.d.cts.map +1 -1
- package/build/modern/useSuspenseQueries.d.ts +244 -20
- package/build/modern/useSuspenseQueries.d.ts.map +1 -1
- package/build/modern/useSuspenseQueries.js.map +1 -1
- package/build/modern/useSuspenseQuery.cjs +48 -8
- package/build/modern/useSuspenseQuery.cjs.map +1 -1
- package/build/modern/useSuspenseQuery.d.cts +48 -8
- package/build/modern/useSuspenseQuery.d.cts.map +1 -1
- package/build/modern/useSuspenseQuery.d.ts +48 -8
- package/build/modern/useSuspenseQuery.d.ts.map +1 -1
- package/build/modern/useSuspenseQuery.js +48 -8
- package/build/modern/useSuspenseQuery.js.map +1 -1
- package/build/query-codemods/eslint.config.js +7 -0
- package/build/query-codemods/root.eslint.config.js +45 -0
- package/package.json +11 -11
- package/src/HydrationBoundary.tsx +0 -1
- package/src/QueryErrorResetBoundary.tsx +12 -12
- package/src/infiniteQueryOptions.ts +41 -55
- package/src/mutationOptions.ts +4 -17
- package/src/queryOptions.ts +50 -73
- package/src/useInfiniteQuery.ts +208 -36
- package/src/useIsFetching.ts +8 -6
- package/src/useMutation.ts +13 -11
- package/src/useMutationState.ts +49 -29
- package/src/useQueries.ts +50 -23
- package/src/useQuery.ts +93 -33
- package/src/useSuspenseInfiniteQuery.ts +57 -7
- package/src/useSuspenseQueries.ts +244 -20
- package/src/useSuspenseQuery.ts +48 -8
package/src/useMutationState.ts
CHANGED
|
@@ -12,22 +12,24 @@ import { useQueryClient } from './QueryClientProvider'
|
|
|
12
12
|
import { useSyncExternalStore } from './utils'
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
* `useIsMutating`
|
|
15
|
+
* The `useIsMutating` hook returns the `number` of mutations that your application currently has `pending`
|
|
16
16
|
* (useful for app-wide loading indicators).
|
|
17
17
|
*
|
|
18
18
|
* @param filters - The {@link MutationFilters} to narrow down the matched mutations.
|
|
19
19
|
* @param queryClient - Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will
|
|
20
20
|
* be used.
|
|
21
|
-
* @returns Will be the `number` of the mutations that your application
|
|
21
|
+
* @returns Will be the `number` of the mutations that your application currently has `pending`.
|
|
22
22
|
*
|
|
23
23
|
* @example
|
|
24
24
|
* ```tsx
|
|
25
25
|
* import { useIsMutating } from '@tanstack/preact-query'
|
|
26
26
|
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
27
|
+
* function PostsMutatingIndicator() {
|
|
28
|
+
* // How many mutations matching the posts prefix are in progress?
|
|
29
|
+
* const isMutatingPosts = useIsMutating({ mutationKey: ['posts'] })
|
|
30
|
+
*
|
|
31
|
+
* return isMutatingPosts ? <span>Saving posts...</span> : null
|
|
32
|
+
* }
|
|
31
33
|
* ```
|
|
32
34
|
*/
|
|
33
35
|
export function useIsMutating(
|
|
@@ -95,10 +97,14 @@ function getResult<
|
|
|
95
97
|
* ```tsx
|
|
96
98
|
* import { useMutationState } from '@tanstack/preact-query'
|
|
97
99
|
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
100
|
+
* function PendingPosts() {
|
|
101
|
+
* const pendingVariables = useMutationState({
|
|
102
|
+
* filters: { status: 'pending' },
|
|
103
|
+
* select: (mutation) => mutation.state.variables,
|
|
104
|
+
* })
|
|
105
|
+
*
|
|
106
|
+
* return <>{pendingVariables.length} posts saving...</>
|
|
107
|
+
* }
|
|
102
108
|
* ```
|
|
103
109
|
*
|
|
104
110
|
* @example
|
|
@@ -108,30 +114,44 @@ function getResult<
|
|
|
108
114
|
*
|
|
109
115
|
* const mutationKey = ['posts']
|
|
110
116
|
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
117
|
+
* function Posts() {
|
|
118
|
+
* // Some mutation that we want to get the state for
|
|
119
|
+
* const mutation = useMutation({
|
|
120
|
+
* mutationKey,
|
|
121
|
+
* mutationFn: createPosts,
|
|
122
|
+
* })
|
|
123
|
+
*
|
|
124
|
+
* const savedPosts = useMutationState({
|
|
125
|
+
* // this mutation key needs to match the mutation key of the given mutation (see above)
|
|
126
|
+
* filters: { mutationKey, status: 'success' },
|
|
127
|
+
* select: (mutation) => mutation.state.data,
|
|
128
|
+
* })
|
|
129
|
+
*
|
|
130
|
+
* return (
|
|
131
|
+
* <button onClick={() => mutation.mutate(['New Post'])}>
|
|
132
|
+
* Create post ({savedPosts.length} saved so far)
|
|
133
|
+
* </button>
|
|
134
|
+
* )
|
|
135
|
+
* }
|
|
122
136
|
* ```
|
|
123
137
|
*
|
|
124
138
|
* @example
|
|
125
|
-
* Access the latest mutation data via the `mutationKey`. Each invocation of `mutate` adds a new
|
|
126
|
-
* mutation cache for `gcTime` milliseconds —
|
|
127
|
-
* latest invocation:
|
|
139
|
+
* Access the latest successful mutation data via the `mutationKey`. Each invocation of `mutate` adds a new
|
|
140
|
+
* entry to the mutation cache for `gcTime` milliseconds — with the `status: 'success'` filter below, check the
|
|
141
|
+
* last item that `useMutationState` returns to get the latest successful invocation:
|
|
128
142
|
* ```tsx
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
143
|
+
* import { useMutationState } from '@tanstack/preact-query'
|
|
144
|
+
*
|
|
145
|
+
* function LatestPost() {
|
|
146
|
+
* const savedPosts = useMutationState({
|
|
147
|
+
* filters: { mutationKey: ['posts'], status: 'success' },
|
|
148
|
+
* select: (mutation) => mutation.state.data,
|
|
149
|
+
* })
|
|
150
|
+
*
|
|
151
|
+
* const latestSavedPost = savedPosts[savedPosts.length - 1]
|
|
133
152
|
*
|
|
134
|
-
*
|
|
153
|
+
* return <>{latestSavedPost ? 'Saved' : 'Nothing saved yet'}</>
|
|
154
|
+
* }
|
|
135
155
|
* ```
|
|
136
156
|
*/
|
|
137
157
|
export function useMutationState<
|
package/src/useQueries.ts
CHANGED
|
@@ -225,8 +225,9 @@ export type QueriesResults<
|
|
|
225
225
|
/**
|
|
226
226
|
* The `useQueries` hook can be used to fetch a variable number of queries.
|
|
227
227
|
*
|
|
228
|
-
* The `queries` key accepts an array with query option objects identical to `useQuery`
|
|
229
|
-
* `
|
|
228
|
+
* The `queries` key accepts an array with query option objects mostly identical to `useQuery` — see the
|
|
229
|
+
* `queries` parameter below for the differences. A custom `QueryClient` is supplied once, as `useQueries`' own
|
|
230
|
+
* top-level second argument, rather than per query.
|
|
230
231
|
*
|
|
231
232
|
* Having the same query key more than once in the array of query objects may cause some data to be shared
|
|
232
233
|
* between queries. To avoid this, consider de-duplicating the queries and map the results back to the desired
|
|
@@ -244,32 +245,58 @@ export type QueriesResults<
|
|
|
244
245
|
* ```tsx
|
|
245
246
|
* import { useQueries } from '@tanstack/preact-query'
|
|
246
247
|
*
|
|
247
|
-
*
|
|
248
|
-
*
|
|
249
|
-
*
|
|
250
|
-
*
|
|
251
|
-
*
|
|
252
|
-
*
|
|
253
|
-
*
|
|
254
|
-
*
|
|
248
|
+
* function Posts({ ids }: { ids: Array<number> }) {
|
|
249
|
+
* const postQueries = useQueries({
|
|
250
|
+
* queries: ids.map((id) => ({
|
|
251
|
+
* queryKey: ['post', id],
|
|
252
|
+
* queryFn: () => fetchPost(id),
|
|
253
|
+
* staleTime: Infinity,
|
|
254
|
+
* })),
|
|
255
|
+
* })
|
|
256
|
+
*
|
|
257
|
+
* return (
|
|
258
|
+
* <ul>
|
|
259
|
+
* {postQueries.map((query, index) => {
|
|
260
|
+
* if (query.isPending) return <li key={ids[index]}>Loading...</li>
|
|
261
|
+
* if (query.isError) return <li key={ids[index]}>Error: {query.error.message}</li>
|
|
262
|
+
* return <li key={ids[index]}>{query.data.title}</li>
|
|
263
|
+
* })}
|
|
264
|
+
* </ul>
|
|
265
|
+
* )
|
|
266
|
+
* }
|
|
255
267
|
* ```
|
|
256
268
|
*
|
|
257
269
|
* @example
|
|
258
270
|
* Combining results into a single value:
|
|
259
271
|
* ```tsx
|
|
260
|
-
*
|
|
261
|
-
*
|
|
262
|
-
*
|
|
263
|
-
*
|
|
264
|
-
*
|
|
265
|
-
*
|
|
266
|
-
*
|
|
267
|
-
*
|
|
268
|
-
*
|
|
269
|
-
*
|
|
270
|
-
*
|
|
271
|
-
*
|
|
272
|
-
*
|
|
272
|
+
* import { useQueries } from '@tanstack/preact-query'
|
|
273
|
+
*
|
|
274
|
+
* function Posts({ ids }: { ids: Array<number> }) {
|
|
275
|
+
* const { data, isPending, isError } = useQueries({
|
|
276
|
+
* queries: ids.map((id) => ({
|
|
277
|
+
* queryKey: ['post', id],
|
|
278
|
+
* queryFn: () => fetchPost(id),
|
|
279
|
+
* })),
|
|
280
|
+
* combine: (postQueries) => {
|
|
281
|
+
* return {
|
|
282
|
+
* data: postQueries.map((query) => query.data),
|
|
283
|
+
* isPending: postQueries.some((query) => query.isPending),
|
|
284
|
+
* isError: postQueries.some((query) => query.isError),
|
|
285
|
+
* }
|
|
286
|
+
* },
|
|
287
|
+
* })
|
|
288
|
+
*
|
|
289
|
+
* if (isPending) return 'Loading...'
|
|
290
|
+
* if (isError) return 'Error loading posts'
|
|
291
|
+
*
|
|
292
|
+
* return (
|
|
293
|
+
* <ul>
|
|
294
|
+
* {data.map((post) => (
|
|
295
|
+
* <li key={post?.id}>{post?.title}</li>
|
|
296
|
+
* ))}
|
|
297
|
+
* </ul>
|
|
298
|
+
* )
|
|
299
|
+
* }
|
|
273
300
|
* ```
|
|
274
301
|
*/
|
|
275
302
|
export function useQueries<
|
package/src/useQuery.ts
CHANGED
|
@@ -28,14 +28,22 @@ import { useBaseQuery } from './useBaseQuery'
|
|
|
28
28
|
* import { useQuery } from '@tanstack/preact-query'
|
|
29
29
|
*
|
|
30
30
|
* function Posts() {
|
|
31
|
-
* // `data` is `Post[]`, never `undefined`, thanks to `initialData
|
|
32
|
-
*
|
|
31
|
+
* // `data` is `Post[]`, never `undefined`, thanks to `initialData` — even if a refetch fails,
|
|
32
|
+
* // so the list stays visible alongside the error.
|
|
33
|
+
* const { data, isError, error } = useQuery({
|
|
33
34
|
* queryKey: ['posts'],
|
|
34
35
|
* queryFn: fetchPosts,
|
|
35
36
|
* initialData: [],
|
|
36
37
|
* })
|
|
37
38
|
*
|
|
38
|
-
* return
|
|
39
|
+
* return (
|
|
40
|
+
* <div>
|
|
41
|
+
* {isError ? <span>Error: {error.message}</span> : null}
|
|
42
|
+
* <ul>
|
|
43
|
+
* {data.map((post) => <li key={post.id}>{post.title}</li>)}
|
|
44
|
+
* </ul>
|
|
45
|
+
* </div>
|
|
46
|
+
* )
|
|
39
47
|
* }
|
|
40
48
|
* ```
|
|
41
49
|
*/
|
|
@@ -54,30 +62,30 @@ export function useQuery<
|
|
|
54
62
|
* @param options - The {@link UndefinedInitialDataOptions} to use — everything you can pass to `useQuery`.
|
|
55
63
|
* @param queryClient - Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will
|
|
56
64
|
* be used.
|
|
57
|
-
* @returns The current query result. `status` is `pending` if there is no cached data
|
|
58
|
-
*
|
|
59
|
-
*
|
|
65
|
+
* @returns The current query result. `status` is `pending` if there is no cached data to display, `error` if
|
|
66
|
+
* the last fetch attempt failed, or `success` if the query has data to display. `isPending`/`isSuccess`/`isError`
|
|
67
|
+
* are derived booleans for convenience.
|
|
60
68
|
*
|
|
61
69
|
* @example
|
|
62
70
|
* ```tsx
|
|
63
|
-
* import {
|
|
64
|
-
*
|
|
65
|
-
* const postsOptions = queryOptions({
|
|
66
|
-
* queryKey: ['posts'],
|
|
67
|
-
* queryFn: fetchPosts,
|
|
68
|
-
* })
|
|
71
|
+
* import { useQuery } from '@tanstack/preact-query'
|
|
69
72
|
*
|
|
70
73
|
* function Posts() {
|
|
71
|
-
* const { status, data, error, isFetching } = useQuery(
|
|
74
|
+
* const { status, data, error, isFetching } = useQuery({
|
|
75
|
+
* queryKey: ['posts'],
|
|
76
|
+
* queryFn: fetchPosts,
|
|
77
|
+
* })
|
|
72
78
|
*
|
|
73
79
|
* if (status === 'pending') return 'Loading...'
|
|
74
80
|
* if (status === 'error') return <span>Error: {error.message}</span>
|
|
75
81
|
*
|
|
76
82
|
* return (
|
|
77
83
|
* <div>
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
84
|
+
* <ul>
|
|
85
|
+
* {data.map((post) => (
|
|
86
|
+
* <li key={post.id}>{post.title}</li>
|
|
87
|
+
* ))}
|
|
88
|
+
* </ul>
|
|
81
89
|
* <div>{isFetching ? 'Background Updating...' : ' '}</div>
|
|
82
90
|
* </div>
|
|
83
91
|
* )
|
|
@@ -98,7 +106,11 @@ export function useQuery<
|
|
|
98
106
|
* if (isPending) return 'Loading...'
|
|
99
107
|
* if (isError) return <span>Error: {error.message}</span>
|
|
100
108
|
*
|
|
101
|
-
* return
|
|
109
|
+
* return (
|
|
110
|
+
* <ul>
|
|
111
|
+
* {data.map((post) => <li key={post.id}>{post.title}</li>)}
|
|
112
|
+
* </ul>
|
|
113
|
+
* )
|
|
102
114
|
* }
|
|
103
115
|
* ```
|
|
104
116
|
*/
|
|
@@ -117,30 +129,30 @@ export function useQuery<
|
|
|
117
129
|
* @param options - The {@link UseQueryOptions} to use — everything you can pass to `useQuery`.
|
|
118
130
|
* @param queryClient - Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will
|
|
119
131
|
* be used.
|
|
120
|
-
* @returns The current query result. `status` is `pending` if there is no cached data
|
|
121
|
-
*
|
|
122
|
-
*
|
|
132
|
+
* @returns The current query result. `status` is `pending` if there is no cached data to display, `error` if
|
|
133
|
+
* the last fetch attempt failed, or `success` if the query has data to display. `isPending`/`isSuccess`/`isError`
|
|
134
|
+
* are derived booleans for convenience.
|
|
123
135
|
*
|
|
124
136
|
* @example
|
|
125
137
|
* ```tsx
|
|
126
|
-
* import {
|
|
127
|
-
*
|
|
128
|
-
* const postsOptions = queryOptions({
|
|
129
|
-
* queryKey: ['posts'],
|
|
130
|
-
* queryFn: fetchPosts,
|
|
131
|
-
* })
|
|
138
|
+
* import { useQuery } from '@tanstack/preact-query'
|
|
132
139
|
*
|
|
133
140
|
* function Posts() {
|
|
134
|
-
* const { status, data, error, isFetching } = useQuery(
|
|
141
|
+
* const { status, data, error, isFetching } = useQuery({
|
|
142
|
+
* queryKey: ['posts'],
|
|
143
|
+
* queryFn: fetchPosts,
|
|
144
|
+
* })
|
|
135
145
|
*
|
|
136
146
|
* if (status === 'pending') return 'Loading...'
|
|
137
147
|
* if (status === 'error') return <span>Error: {error.message}</span>
|
|
138
148
|
*
|
|
139
149
|
* return (
|
|
140
150
|
* <div>
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
151
|
+
* <ul>
|
|
152
|
+
* {data.map((post) => (
|
|
153
|
+
* <li key={post.id}>{post.title}</li>
|
|
154
|
+
* ))}
|
|
155
|
+
* </ul>
|
|
144
156
|
* <div>{isFetching ? 'Background Updating...' : ' '}</div>
|
|
145
157
|
* </div>
|
|
146
158
|
* )
|
|
@@ -148,6 +160,26 @@ export function useQuery<
|
|
|
148
160
|
* ```
|
|
149
161
|
*
|
|
150
162
|
* @example
|
|
163
|
+
* `select` derives whatever `data` a component needs from the cached value, without changing what's
|
|
164
|
+
* actually stored in the cache — the cache still holds the full `Post[]`, but `data` here is a `number`:
|
|
165
|
+
* ```tsx
|
|
166
|
+
* import { useQuery } from '@tanstack/preact-query'
|
|
167
|
+
*
|
|
168
|
+
* function PostCount() {
|
|
169
|
+
* const { data, isPending, isError, error } = useQuery({
|
|
170
|
+
* queryKey: ['posts'],
|
|
171
|
+
* queryFn: fetchPosts,
|
|
172
|
+
* select: (posts) => posts.length,
|
|
173
|
+
* })
|
|
174
|
+
*
|
|
175
|
+
* if (isPending) return 'Loading...'
|
|
176
|
+
* if (isError) return <span>Error: {error.message}</span>
|
|
177
|
+
*
|
|
178
|
+
* return <span>{data} posts</span>
|
|
179
|
+
* }
|
|
180
|
+
* ```
|
|
181
|
+
*
|
|
182
|
+
* @example
|
|
151
183
|
* A dependent query, only enabled once `postId` is set — use `isLoading`, not `isPending`, so the
|
|
152
184
|
* loading state doesn't show while the query is disabled:
|
|
153
185
|
* ```tsx
|
|
@@ -169,6 +201,28 @@ export function useQuery<
|
|
|
169
201
|
* ```
|
|
170
202
|
*
|
|
171
203
|
* @example
|
|
204
|
+
* The same dependent query, type safe: `skipToken` disables the query without needing the
|
|
205
|
+
* non-null assertion above, since `queryFn` is only ever called when `postId` is defined.
|
|
206
|
+
* `refetch` doesn't work while `queryFn` is `skipToken` — use `enabled: false` instead if you
|
|
207
|
+
* need to trigger the query manually:
|
|
208
|
+
* ```tsx
|
|
209
|
+
* import { skipToken, useQuery } from '@tanstack/preact-query'
|
|
210
|
+
*
|
|
211
|
+
* function Post({ postId }: { postId: number | undefined }) {
|
|
212
|
+
* const { data, isLoading, isError, error } = useQuery({
|
|
213
|
+
* queryKey: ['post', postId],
|
|
214
|
+
* queryFn: postId != null ? () => fetchPost(postId) : skipToken,
|
|
215
|
+
* })
|
|
216
|
+
*
|
|
217
|
+
* if (postId == null) return 'Select a post'
|
|
218
|
+
* if (isLoading) return 'Loading...'
|
|
219
|
+
* if (isError) return <span>Error: {error.message}</span>
|
|
220
|
+
*
|
|
221
|
+
* return <h1>{data?.title}</h1>
|
|
222
|
+
* }
|
|
223
|
+
* ```
|
|
224
|
+
*
|
|
225
|
+
* @example
|
|
172
226
|
* Seeding a detail query from an already-cached list, to skip the loading state:
|
|
173
227
|
* ```tsx
|
|
174
228
|
* import { useQuery, useQueryClient } from '@tanstack/preact-query'
|
|
@@ -176,7 +230,7 @@ export function useQuery<
|
|
|
176
230
|
* function Post({ postId }: { postId: number }) {
|
|
177
231
|
* const queryClient = useQueryClient()
|
|
178
232
|
*
|
|
179
|
-
* const { data } = useQuery({
|
|
233
|
+
* const { data, isError, error } = useQuery({
|
|
180
234
|
* queryKey: ['post', postId],
|
|
181
235
|
* queryFn: () => fetchPost(postId),
|
|
182
236
|
* initialData: () =>
|
|
@@ -185,6 +239,8 @@ export function useQuery<
|
|
|
185
239
|
* ?.find((post) => post.id === postId),
|
|
186
240
|
* })
|
|
187
241
|
*
|
|
242
|
+
* if (isError) return <span>Error: {error.message}</span>
|
|
243
|
+
*
|
|
188
244
|
* return <h1>{data?.title}</h1>
|
|
189
245
|
* }
|
|
190
246
|
* ```
|
|
@@ -198,15 +254,19 @@ export function useQuery<
|
|
|
198
254
|
* function Posts() {
|
|
199
255
|
* const [page, setPage] = useState(0)
|
|
200
256
|
*
|
|
201
|
-
* const { data, isPlaceholderData } = useQuery({
|
|
257
|
+
* const { data, isPlaceholderData, isError, error } = useQuery({
|
|
202
258
|
* queryKey: ['posts', page],
|
|
203
259
|
* queryFn: () => fetchPosts(page),
|
|
204
260
|
* placeholderData: keepPreviousData,
|
|
205
261
|
* })
|
|
206
262
|
*
|
|
263
|
+
* if (isError) return <span>Error: {error.message}</span>
|
|
264
|
+
*
|
|
207
265
|
* return (
|
|
208
266
|
* <div>
|
|
209
|
-
*
|
|
267
|
+
* <ul>
|
|
268
|
+
* {data?.map((post) => <li key={post.id}>{post.title}</li>)}
|
|
269
|
+
* </ul>
|
|
210
270
|
* <button
|
|
211
271
|
* disabled={isPlaceholderData}
|
|
212
272
|
* onClick={() => setPage((old) => old + 1)}
|
|
@@ -21,6 +21,13 @@ import { useBaseQuery } from './useBaseQuery'
|
|
|
21
21
|
*
|
|
22
22
|
* Caveat: cancellation does not work.
|
|
23
23
|
*
|
|
24
|
+
* @remarks Multiple suspenseful query calls in the same component suspend serially, causing a request
|
|
25
|
+
* waterfall — each one blocks rendering until it resolves, so the next doesn't even start fetching until
|
|
26
|
+
* then. There's no way to parallelize multiple infinite queries under Suspense. Also keep in mind that
|
|
27
|
+
* imperative fetch calls, such as `fetchNextPage`, may interfere with the default refetch behavior,
|
|
28
|
+
* resulting in outdated data. Make sure to call these functions only in response to user actions, or add
|
|
29
|
+
* conditions like `hasNextPage && !isFetching`.
|
|
30
|
+
* @see {@link useInfiniteQuery} for the non-Suspense version of this hook.
|
|
24
31
|
* @param options - The {@link UseSuspenseInfiniteQueryOptions} to use — the same options as `useInfiniteQuery`, minus the ones listed above.
|
|
25
32
|
* @param queryClient - Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will
|
|
26
33
|
* be used.
|
|
@@ -29,9 +36,17 @@ import { useBaseQuery } from './useBaseQuery'
|
|
|
29
36
|
* accordingly).
|
|
30
37
|
*
|
|
31
38
|
* @example
|
|
39
|
+
* The query error is thrown if a fetch fails and no cached data exists yet, so an error boundary is
|
|
40
|
+
* required around `<Suspense>`. A failed background refetch instead continues to render the cached data.
|
|
41
|
+
* Use {@link QueryErrorResetBoundary} to let the user retry after such an error:
|
|
32
42
|
* ```tsx
|
|
33
43
|
* import { Suspense } from 'preact/compat'
|
|
34
|
-
* import {
|
|
44
|
+
* import { useErrorBoundary } from 'preact/hooks'
|
|
45
|
+
* import {
|
|
46
|
+
* QueryErrorResetBoundary,
|
|
47
|
+
* useSuspenseInfiniteQuery,
|
|
48
|
+
* } from '@tanstack/preact-query'
|
|
49
|
+
* import type { ComponentChildren } from 'preact'
|
|
35
50
|
*
|
|
36
51
|
* function Projects() {
|
|
37
52
|
* // `data` is guaranteed to be defined here — no `isPending` check needed.
|
|
@@ -45,9 +60,11 @@ import { useBaseQuery } from './useBaseQuery'
|
|
|
45
60
|
*
|
|
46
61
|
* return (
|
|
47
62
|
* <div>
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
63
|
+
* <ul>
|
|
64
|
+
* {data.pages.map((page) =>
|
|
65
|
+
* page.projects.map((project) => <li key={project.id}>{project.name}</li>),
|
|
66
|
+
* )}
|
|
67
|
+
* </ul>
|
|
51
68
|
* <button
|
|
52
69
|
* onClick={() => fetchNextPage()}
|
|
53
70
|
* disabled={!hasNextPage || isFetching}
|
|
@@ -64,11 +81,44 @@ import { useBaseQuery } from './useBaseQuery'
|
|
|
64
81
|
*
|
|
65
82
|
* function App() {
|
|
66
83
|
* return (
|
|
67
|
-
* <
|
|
68
|
-
*
|
|
69
|
-
*
|
|
84
|
+
* <QueryErrorResetBoundary>
|
|
85
|
+
* {({ reset }) => (
|
|
86
|
+
* <ErrorBoundary
|
|
87
|
+
* onReset={reset}
|
|
88
|
+
* fallbackRender={({ resetErrorBoundary }) => (
|
|
89
|
+
* <div>
|
|
90
|
+
* There was an error!
|
|
91
|
+
* <button onClick={() => resetErrorBoundary()}>Try again</button>
|
|
92
|
+
* </div>
|
|
93
|
+
* )}
|
|
94
|
+
* >
|
|
95
|
+
* <Suspense fallback={<h1>Loading projects...</h1>}>
|
|
96
|
+
* <Projects />
|
|
97
|
+
* </Suspense>
|
|
98
|
+
* </ErrorBoundary>
|
|
99
|
+
* )}
|
|
100
|
+
* </QueryErrorResetBoundary>
|
|
70
101
|
* )
|
|
71
102
|
* }
|
|
103
|
+
*
|
|
104
|
+
* function ErrorBoundary({
|
|
105
|
+
* children,
|
|
106
|
+
* onReset,
|
|
107
|
+
* fallbackRender,
|
|
108
|
+
* }: {
|
|
109
|
+
* children: ComponentChildren
|
|
110
|
+
* onReset: () => void
|
|
111
|
+
* fallbackRender: (props: {
|
|
112
|
+
* error: Error
|
|
113
|
+
* resetErrorBoundary: () => void
|
|
114
|
+
* }) => ComponentChildren
|
|
115
|
+
* }) {
|
|
116
|
+
* const [error, resetErrorBoundary] = useErrorBoundary(() => onReset())
|
|
117
|
+
*
|
|
118
|
+
* if (error) return fallbackRender({ error, resetErrorBoundary })
|
|
119
|
+
*
|
|
120
|
+
* return children
|
|
121
|
+
* }
|
|
72
122
|
* ```
|
|
73
123
|
*/
|
|
74
124
|
export function useSuspenseInfiniteQuery<
|