@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/queryOptions.ts
CHANGED
|
@@ -59,7 +59,9 @@ export type UnusedSkipTokenOptions<
|
|
|
59
59
|
> & {
|
|
60
60
|
/**
|
|
61
61
|
* `skipToken` is not allowed as a value here — this overload is selected when no `initialData` is set. If
|
|
62
|
-
* you don't intend to run the query yet,
|
|
62
|
+
* you don't intend to run the query yet, set `enabled: false` — omitting `queryFn` alone still triggers a
|
|
63
|
+
* fetch that fails with "Missing queryFn" unless `enabled` is `false` or a default query function has been
|
|
64
|
+
* defined. A default query function only supplies `queryFn`; it doesn't defer the fetch on its own.
|
|
63
65
|
*/
|
|
64
66
|
queryFn?: Exclude<
|
|
65
67
|
UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>['queryFn'],
|
|
@@ -108,6 +110,7 @@ export type DefinedInitialDataOptions<
|
|
|
108
110
|
* This overload is selected when `initialData` is set, so the resulting `data` is never `undefined`.
|
|
109
111
|
*
|
|
110
112
|
* @see {@link useQuery} to run a query with these options.
|
|
113
|
+
* @see [The Query Options API](https://tkdodo.eu/blog/the-query-options-api) for more on this pattern.
|
|
111
114
|
* @param options - The {@link DefinedInitialDataOptions} to use — everything you can pass to `useQuery`, with `initialData` set.
|
|
112
115
|
* @returns The same options object, typed so that `queryKey` carries the inferred data type.
|
|
113
116
|
*
|
|
@@ -122,9 +125,18 @@ export type DefinedInitialDataOptions<
|
|
|
122
125
|
* })
|
|
123
126
|
*
|
|
124
127
|
* function Posts() {
|
|
125
|
-
* // `data` is `Post[]`, never `undefined`, thanks to `initialData
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
+
* // `data` is `Post[]`, never `undefined`, thanks to `initialData` — even if a refetch fails,
|
|
129
|
+
* // so the list stays visible alongside the error.
|
|
130
|
+
* const { data, isError, error } = useQuery(postsOptions)
|
|
131
|
+
*
|
|
132
|
+
* return (
|
|
133
|
+
* <div>
|
|
134
|
+
* {isError ? <span>Error: {error.message}</span> : null}
|
|
135
|
+
* <ul>
|
|
136
|
+
* {data.map((post) => <li key={post.id}>{post.title}</li>)}
|
|
137
|
+
* </ul>
|
|
138
|
+
* </div>
|
|
139
|
+
* )
|
|
128
140
|
* }
|
|
129
141
|
* ```
|
|
130
142
|
*/
|
|
@@ -144,23 +156,14 @@ export function queryOptions<
|
|
|
144
156
|
* is the query key to generate options for.
|
|
145
157
|
*
|
|
146
158
|
* @see {@link useQuery} to run a query with these options.
|
|
159
|
+
* @see [The Query Options API](https://tkdodo.eu/blog/the-query-options-api) for more on this pattern.
|
|
147
160
|
* @param options - The {@link UnusedSkipTokenOptions} to use — everything you can pass to `useQuery`.
|
|
148
161
|
* @returns The same options object, typed so that `queryKey` carries the inferred data type.
|
|
149
162
|
*
|
|
150
163
|
* @example
|
|
164
|
+
* A parameterized factory, so the same options object can be reused per `id`:
|
|
151
165
|
* ```tsx
|
|
152
|
-
* import { queryOptions } from '@tanstack/preact-query'
|
|
153
|
-
*
|
|
154
|
-
* export const postsOptions = queryOptions({
|
|
155
|
-
* queryKey: ['posts'],
|
|
156
|
-
* queryFn: fetchPosts,
|
|
157
|
-
* })
|
|
158
|
-
* ```
|
|
159
|
-
*
|
|
160
|
-
* @example
|
|
161
|
-
* A parameterized factory, reused across a hook and an imperative call with the same cache entry:
|
|
162
|
-
* ```tsx
|
|
163
|
-
* import { noop, queryOptions, useQuery } from '@tanstack/preact-query'
|
|
166
|
+
* import { queryOptions, useQuery } from '@tanstack/preact-query'
|
|
164
167
|
*
|
|
165
168
|
* export const postOptions = (id: string) =>
|
|
166
169
|
* queryOptions({
|
|
@@ -169,33 +172,13 @@ export function queryOptions<
|
|
|
169
172
|
* })
|
|
170
173
|
*
|
|
171
174
|
* function Post({ id }: { id: string }) {
|
|
172
|
-
* const { data } = useQuery(postOptions(id))
|
|
173
|
-
* return <h1>{data?.title}</h1>
|
|
174
|
-
* }
|
|
175
|
-
*
|
|
176
|
-
* // Elsewhere, e.g. to warm the cache before rendering `<Post>`:
|
|
177
|
-
* queryClient.query(postOptions(id)).catch(noop)
|
|
178
|
-
* ```
|
|
179
|
-
*
|
|
180
|
-
* @example
|
|
181
|
-
* The same options object works with every API that accepts query options:
|
|
182
|
-
* ```tsx
|
|
183
|
-
* import {
|
|
184
|
-
* noop,
|
|
185
|
-
* queryOptions,
|
|
186
|
-
* useQuery,
|
|
187
|
-
* useSuspenseQuery,
|
|
188
|
-
* } from '@tanstack/preact-query'
|
|
175
|
+
* const { data, isPending, isError, error } = useQuery(postOptions(id))
|
|
189
176
|
*
|
|
190
|
-
*
|
|
191
|
-
*
|
|
192
|
-
* queryFn: fetchTodos,
|
|
193
|
-
* })
|
|
177
|
+
* if (isPending) return 'Loading...'
|
|
178
|
+
* if (isError) return <span>Error: {error.message}</span>
|
|
194
179
|
*
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
* queryClient.query(todosOptions).catch(noop)
|
|
198
|
-
* queryClient.getQueryData(todosOptions.queryKey) // typed as Array<Todo> | undefined
|
|
180
|
+
* return <h1>{data.title}</h1>
|
|
181
|
+
* }
|
|
199
182
|
* ```
|
|
200
183
|
*/
|
|
201
184
|
export function queryOptions<
|
|
@@ -214,23 +197,15 @@ export function queryOptions<
|
|
|
214
197
|
* is the query key to generate options for.
|
|
215
198
|
*
|
|
216
199
|
* @see {@link useQuery} to run a query with these options.
|
|
200
|
+
* @see [The Query Options API](https://tkdodo.eu/blog/the-query-options-api) for more on this pattern.
|
|
217
201
|
* @param options - The {@link UndefinedInitialDataOptions} to use — everything you can pass to `useQuery`.
|
|
218
202
|
* @returns The same options object, typed so that `queryKey` carries the inferred data type.
|
|
203
|
+
* @remarks This is the only overload that accepts `queryFn: skipToken`, shown below.
|
|
219
204
|
*
|
|
220
205
|
* @example
|
|
206
|
+
* A parameterized factory, so the same options object can be reused per `id`:
|
|
221
207
|
* ```tsx
|
|
222
|
-
* import { queryOptions } from '@tanstack/preact-query'
|
|
223
|
-
*
|
|
224
|
-
* export const postsOptions = queryOptions({
|
|
225
|
-
* queryKey: ['posts'],
|
|
226
|
-
* queryFn: fetchPosts,
|
|
227
|
-
* })
|
|
228
|
-
* ```
|
|
229
|
-
*
|
|
230
|
-
* @example
|
|
231
|
-
* A parameterized factory, reused across a hook and an imperative call with the same cache entry:
|
|
232
|
-
* ```tsx
|
|
233
|
-
* import { noop, queryOptions, useQuery } from '@tanstack/preact-query'
|
|
208
|
+
* import { queryOptions, useQuery } from '@tanstack/preact-query'
|
|
234
209
|
*
|
|
235
210
|
* export const postOptions = (id: string) =>
|
|
236
211
|
* queryOptions({
|
|
@@ -239,33 +214,35 @@ export function queryOptions<
|
|
|
239
214
|
* })
|
|
240
215
|
*
|
|
241
216
|
* function Post({ id }: { id: string }) {
|
|
242
|
-
* const { data } = useQuery(postOptions(id))
|
|
243
|
-
*
|
|
244
|
-
*
|
|
217
|
+
* const { data, isPending, isError, error } = useQuery(postOptions(id))
|
|
218
|
+
*
|
|
219
|
+
* if (isPending) return 'Loading...'
|
|
220
|
+
* if (isError) return <span>Error: {error.message}</span>
|
|
245
221
|
*
|
|
246
|
-
*
|
|
247
|
-
*
|
|
222
|
+
* return <h1>{data.title}</h1>
|
|
223
|
+
* }
|
|
248
224
|
* ```
|
|
249
225
|
*
|
|
250
226
|
* @example
|
|
251
|
-
*
|
|
227
|
+
* A factory that disables the query, type safe, until `postId` is set:
|
|
252
228
|
* ```tsx
|
|
253
|
-
* import {
|
|
254
|
-
* noop,
|
|
255
|
-
* queryOptions,
|
|
256
|
-
* useQuery,
|
|
257
|
-
* useSuspenseQuery,
|
|
258
|
-
* } from '@tanstack/preact-query'
|
|
229
|
+
* import { queryOptions, skipToken, useQuery } from '@tanstack/preact-query'
|
|
259
230
|
*
|
|
260
|
-
* const
|
|
261
|
-
*
|
|
262
|
-
*
|
|
263
|
-
*
|
|
231
|
+
* export const postOptions = (postId: number | undefined) =>
|
|
232
|
+
* queryOptions({
|
|
233
|
+
* queryKey: ['post', postId],
|
|
234
|
+
* queryFn: postId != null ? () => fetchPost(postId) : skipToken,
|
|
235
|
+
* })
|
|
236
|
+
*
|
|
237
|
+
* function Post({ postId }: { postId: number | undefined }) {
|
|
238
|
+
* const { data, isLoading, isError, error } = useQuery(postOptions(postId))
|
|
239
|
+
*
|
|
240
|
+
* if (postId == null) return 'Select a post'
|
|
241
|
+
* if (isLoading) return 'Loading...'
|
|
242
|
+
* if (isError) return <span>Error: {error.message}</span>
|
|
264
243
|
*
|
|
265
|
-
*
|
|
266
|
-
*
|
|
267
|
-
* queryClient.query(todosOptions).catch(noop)
|
|
268
|
-
* queryClient.getQueryData(todosOptions.queryKey) // typed as Array<Todo> | undefined
|
|
244
|
+
* return <h1>{data?.title}</h1>
|
|
245
|
+
* }
|
|
269
246
|
* ```
|
|
270
247
|
*/
|
|
271
248
|
export function queryOptions<
|
package/src/useInfiniteQuery.ts
CHANGED
|
@@ -19,7 +19,7 @@ import type {
|
|
|
19
19
|
import { useBaseQuery } from './useBaseQuery'
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
|
-
* The options for `useInfiniteQuery` are identical to `useQuery`, with the addition of
|
|
22
|
+
* The options for `useInfiniteQuery` are identical to `useQuery`, with the addition of
|
|
23
23
|
* `initialPageParam`, `getNextPageParam`, `getPreviousPageParam`, and `maxPages`.
|
|
24
24
|
*
|
|
25
25
|
* This overload is selected when `initialData` is set.
|
|
@@ -31,16 +31,19 @@ import { useBaseQuery } from './useBaseQuery'
|
|
|
31
31
|
* @param options - The {@link DefinedInitialDataInfiniteOptions} to use — everything you can pass to `useInfiniteQuery`, with `initialData` set.
|
|
32
32
|
* @param queryClient - Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will
|
|
33
33
|
* be used.
|
|
34
|
-
* @returns The same properties as `useQuery`, with the addition of `
|
|
35
|
-
* `
|
|
36
|
-
* `
|
|
34
|
+
* @returns The same properties as `useQuery`, with the addition of `fetchNextPage`, `fetchPreviousPage`,
|
|
35
|
+
* `hasNextPage`, `hasPreviousPage`, `isFetchingNextPage`, and `isFetchingPreviousPage`. `data.pages` and
|
|
36
|
+
* `data.pageParams` are also added, as long as a `select` doesn't change `TData` away from its default
|
|
37
|
+
* `InfiniteData<TQueryFnData>` shape.
|
|
37
38
|
*
|
|
38
39
|
* @example
|
|
39
40
|
* ```tsx
|
|
40
41
|
* import { useInfiniteQuery } from '@tanstack/preact-query'
|
|
41
42
|
*
|
|
42
43
|
* function Projects() {
|
|
43
|
-
*
|
|
44
|
+
* // `data` is never `undefined`, thanks to `initialData` — even if a refetch fails, so the
|
|
45
|
+
* // list stays visible alongside the error.
|
|
46
|
+
* const { data, isError, error } = useInfiniteQuery({
|
|
44
47
|
* queryKey: ['projects'],
|
|
45
48
|
* queryFn: ({ pageParam }) => fetchProjects(pageParam),
|
|
46
49
|
* initialPageParam: 0,
|
|
@@ -48,7 +51,14 @@ import { useBaseQuery } from './useBaseQuery'
|
|
|
48
51
|
* initialData: { pages: [], pageParams: [] },
|
|
49
52
|
* })
|
|
50
53
|
*
|
|
51
|
-
* return
|
|
54
|
+
* return (
|
|
55
|
+
* <div>
|
|
56
|
+
* {isError ? <span>Error: {error.message}</span> : null}
|
|
57
|
+
* <ul>
|
|
58
|
+
* {data.pages.map((page) => page.projects.map((p) => <li key={p.id}>{p.name}</li>))}
|
|
59
|
+
* </ul>
|
|
60
|
+
* </div>
|
|
61
|
+
* )
|
|
52
62
|
* }
|
|
53
63
|
* ```
|
|
54
64
|
*/
|
|
@@ -70,7 +80,7 @@ export function useInfiniteQuery<
|
|
|
70
80
|
): DefinedUseInfiniteQueryResult<TData, TError>
|
|
71
81
|
|
|
72
82
|
/**
|
|
73
|
-
* The options for `useInfiniteQuery` are identical to `useQuery`, with the addition of
|
|
83
|
+
* The options for `useInfiniteQuery` are identical to `useQuery`, with the addition of
|
|
74
84
|
* `initialPageParam`, `getNextPageParam`, `getPreviousPageParam`, and `maxPages`.
|
|
75
85
|
*
|
|
76
86
|
* @remarks Keep in mind that imperative fetch calls, such as `fetchNextPage`, may interfere with the default
|
|
@@ -80,16 +90,18 @@ export function useInfiniteQuery<
|
|
|
80
90
|
* @param options - The {@link UndefinedInitialDataInfiniteOptions} to use — everything you can pass to `useInfiniteQuery`.
|
|
81
91
|
* @param queryClient - Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will
|
|
82
92
|
* be used.
|
|
83
|
-
* @returns The same properties as `useQuery`, with the addition of `
|
|
84
|
-
* `
|
|
85
|
-
* `
|
|
93
|
+
* @returns The same properties as `useQuery`, with the addition of `fetchNextPage`, `fetchPreviousPage`,
|
|
94
|
+
* `hasNextPage`, `hasPreviousPage`, `isFetchingNextPage`, and `isFetchingPreviousPage`. `data.pages` and
|
|
95
|
+
* `data.pageParams` are also added, as long as a `select` doesn't change `TData` away from its default
|
|
96
|
+
* `InfiniteData<TQueryFnData>` shape.
|
|
86
97
|
*
|
|
87
98
|
* @example
|
|
99
|
+
* Fetching the next page from a "Load More" button click:
|
|
88
100
|
* ```tsx
|
|
89
101
|
* import { useInfiniteQuery } from '@tanstack/preact-query'
|
|
90
102
|
*
|
|
91
103
|
* function Projects() {
|
|
92
|
-
* const { data, fetchNextPage, hasNextPage, isFetching, isFetchingNextPage } =
|
|
104
|
+
* const { data, isPending, isError, error, fetchNextPage, hasNextPage, isFetching, isFetchingNextPage } =
|
|
93
105
|
* useInfiniteQuery({
|
|
94
106
|
* queryKey: ['projects'],
|
|
95
107
|
* queryFn: ({ pageParam }) => fetchProjects(pageParam),
|
|
@@ -97,17 +109,81 @@ export function useInfiniteQuery<
|
|
|
97
109
|
* getNextPageParam: (lastPage) => lastPage.nextId,
|
|
98
110
|
* })
|
|
99
111
|
*
|
|
112
|
+
* if (isPending) return 'Loading...'
|
|
113
|
+
* if (isError) return <span>Error: {error.message}</span>
|
|
114
|
+
*
|
|
100
115
|
* return (
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
116
|
+
* <>
|
|
117
|
+
* <ul>
|
|
118
|
+
* {data.pages.map((page) =>
|
|
119
|
+
* page.projects.map((project) => <li key={project.id}>{project.name}</li>),
|
|
120
|
+
* )}
|
|
121
|
+
* </ul>
|
|
122
|
+
* <button
|
|
123
|
+
* onClick={() => fetchNextPage()}
|
|
124
|
+
* disabled={!hasNextPage || isFetching}
|
|
125
|
+
* >
|
|
126
|
+
* {isFetchingNextPage
|
|
127
|
+
* ? 'Loading more...'
|
|
128
|
+
* : hasNextPage
|
|
129
|
+
* ? 'Load More'
|
|
130
|
+
* : 'Nothing more to load'}
|
|
131
|
+
* </button>
|
|
132
|
+
* </>
|
|
133
|
+
* )
|
|
134
|
+
* }
|
|
135
|
+
* ```
|
|
136
|
+
*
|
|
137
|
+
* @example
|
|
138
|
+
* Fetching the next page automatically as the user scrolls, using an `IntersectionObserver` on a
|
|
139
|
+
* sentinel element after the list:
|
|
140
|
+
* ```tsx
|
|
141
|
+
* import { useInfiniteQuery } from '@tanstack/preact-query'
|
|
142
|
+
* import { useEffect, useRef } from 'preact/hooks'
|
|
143
|
+
*
|
|
144
|
+
* function Projects() {
|
|
145
|
+
* const {
|
|
146
|
+
* data,
|
|
147
|
+
* isPending,
|
|
148
|
+
* isError,
|
|
149
|
+
* error,
|
|
150
|
+
* fetchNextPage,
|
|
151
|
+
* hasNextPage,
|
|
152
|
+
* isFetching,
|
|
153
|
+
* isFetchingNextPage,
|
|
154
|
+
* } = useInfiniteQuery({
|
|
155
|
+
* queryKey: ['projects'],
|
|
156
|
+
* queryFn: ({ pageParam }) => fetchProjects(pageParam),
|
|
157
|
+
* initialPageParam: 0,
|
|
158
|
+
* getNextPageParam: (lastPage) => lastPage.nextId,
|
|
159
|
+
* })
|
|
160
|
+
*
|
|
161
|
+
* const sentinelRef = useRef<HTMLDivElement>(null)
|
|
162
|
+
*
|
|
163
|
+
* useEffect(() => {
|
|
164
|
+
* const sentinel = sentinelRef.current
|
|
165
|
+
* if (sentinel == null || !hasNextPage || isFetching) return
|
|
166
|
+
*
|
|
167
|
+
* const observer = new IntersectionObserver(([entry]) => {
|
|
168
|
+
* if (entry?.isIntersecting) fetchNextPage()
|
|
169
|
+
* })
|
|
170
|
+
* observer.observe(sentinel)
|
|
171
|
+
*
|
|
172
|
+
* return () => observer.disconnect()
|
|
173
|
+
* }, [hasNextPage, isFetching, fetchNextPage])
|
|
174
|
+
*
|
|
175
|
+
* if (isPending) return 'Loading...'
|
|
176
|
+
* if (isError) return <span>Error: {error.message}</span>
|
|
177
|
+
*
|
|
178
|
+
* return (
|
|
179
|
+
* <>
|
|
180
|
+
* <ul>
|
|
181
|
+
* {data.pages.map((page) =>
|
|
182
|
+
* page.projects.map((project) => <li key={project.id}>{project.name}</li>),
|
|
183
|
+
* )}
|
|
184
|
+
* </ul>
|
|
185
|
+
* <div ref={sentinelRef}>{isFetchingNextPage ? 'Loading more...' : null}</div>
|
|
186
|
+
* </>
|
|
111
187
|
* )
|
|
112
188
|
* }
|
|
113
189
|
* ```
|
|
@@ -130,7 +206,7 @@ export function useInfiniteQuery<
|
|
|
130
206
|
): UseInfiniteQueryResult<TData, TError>
|
|
131
207
|
|
|
132
208
|
/**
|
|
133
|
-
* The options for `useInfiniteQuery` are identical to `useQuery`, with the addition of
|
|
209
|
+
* The options for `useInfiniteQuery` are identical to `useQuery`, with the addition of
|
|
134
210
|
* `initialPageParam`, `getNextPageParam`, `getPreviousPageParam`, and `maxPages`.
|
|
135
211
|
*
|
|
136
212
|
* @remarks Keep in mind that imperative fetch calls, such as `fetchNextPage`, may interfere with the default
|
|
@@ -140,16 +216,18 @@ export function useInfiniteQuery<
|
|
|
140
216
|
* @param options - The {@link UseInfiniteQueryOptions} to use — everything you can pass to `useInfiniteQuery`.
|
|
141
217
|
* @param queryClient - Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will
|
|
142
218
|
* be used.
|
|
143
|
-
* @returns The same properties as `useQuery`, with the addition of `
|
|
144
|
-
* `
|
|
145
|
-
* `
|
|
219
|
+
* @returns The same properties as `useQuery`, with the addition of `fetchNextPage`, `fetchPreviousPage`,
|
|
220
|
+
* `hasNextPage`, `hasPreviousPage`, `isFetchingNextPage`, and `isFetchingPreviousPage`. `data.pages` and
|
|
221
|
+
* `data.pageParams` are also added, as long as a `select` doesn't change `TData` away from its default
|
|
222
|
+
* `InfiniteData<TQueryFnData>` shape.
|
|
146
223
|
*
|
|
147
224
|
* @example
|
|
225
|
+
* Fetching the next page from a "Load More" button click:
|
|
148
226
|
* ```tsx
|
|
149
227
|
* import { useInfiniteQuery } from '@tanstack/preact-query'
|
|
150
228
|
*
|
|
151
229
|
* function Projects() {
|
|
152
|
-
* const { data, fetchNextPage, hasNextPage, isFetching, isFetchingNextPage } =
|
|
230
|
+
* const { data, isPending, isError, error, fetchNextPage, hasNextPage, isFetching, isFetchingNextPage } =
|
|
153
231
|
* useInfiniteQuery({
|
|
154
232
|
* queryKey: ['projects'],
|
|
155
233
|
* queryFn: ({ pageParam }) => fetchProjects(pageParam),
|
|
@@ -157,17 +235,111 @@ export function useInfiniteQuery<
|
|
|
157
235
|
* getNextPageParam: (lastPage) => lastPage.nextId,
|
|
158
236
|
* })
|
|
159
237
|
*
|
|
238
|
+
* if (isPending) return 'Loading...'
|
|
239
|
+
* if (isError) return <span>Error: {error.message}</span>
|
|
240
|
+
*
|
|
241
|
+
* return (
|
|
242
|
+
* <>
|
|
243
|
+
* <ul>
|
|
244
|
+
* {data.pages.map((page) =>
|
|
245
|
+
* page.projects.map((project) => <li key={project.id}>{project.name}</li>),
|
|
246
|
+
* )}
|
|
247
|
+
* </ul>
|
|
248
|
+
* <button
|
|
249
|
+
* onClick={() => fetchNextPage()}
|
|
250
|
+
* disabled={!hasNextPage || isFetching}
|
|
251
|
+
* >
|
|
252
|
+
* {isFetchingNextPage
|
|
253
|
+
* ? 'Loading more...'
|
|
254
|
+
* : hasNextPage
|
|
255
|
+
* ? 'Load More'
|
|
256
|
+
* : 'Nothing more to load'}
|
|
257
|
+
* </button>
|
|
258
|
+
* </>
|
|
259
|
+
* )
|
|
260
|
+
* }
|
|
261
|
+
* ```
|
|
262
|
+
*
|
|
263
|
+
* @example
|
|
264
|
+
* Fetching the next page automatically as the user scrolls, using an `IntersectionObserver` on a
|
|
265
|
+
* sentinel element after the list:
|
|
266
|
+
* ```tsx
|
|
267
|
+
* import { useInfiniteQuery } from '@tanstack/preact-query'
|
|
268
|
+
* import { useEffect, useRef } from 'preact/hooks'
|
|
269
|
+
*
|
|
270
|
+
* function Projects() {
|
|
271
|
+
* const {
|
|
272
|
+
* data,
|
|
273
|
+
* isPending,
|
|
274
|
+
* isError,
|
|
275
|
+
* error,
|
|
276
|
+
* fetchNextPage,
|
|
277
|
+
* hasNextPage,
|
|
278
|
+
* isFetching,
|
|
279
|
+
* isFetchingNextPage,
|
|
280
|
+
* } = useInfiniteQuery({
|
|
281
|
+
* queryKey: ['projects'],
|
|
282
|
+
* queryFn: ({ pageParam }) => fetchProjects(pageParam),
|
|
283
|
+
* initialPageParam: 0,
|
|
284
|
+
* getNextPageParam: (lastPage) => lastPage.nextId,
|
|
285
|
+
* })
|
|
286
|
+
*
|
|
287
|
+
* const sentinelRef = useRef<HTMLDivElement>(null)
|
|
288
|
+
*
|
|
289
|
+
* useEffect(() => {
|
|
290
|
+
* const sentinel = sentinelRef.current
|
|
291
|
+
* if (sentinel == null || !hasNextPage || isFetching) return
|
|
292
|
+
*
|
|
293
|
+
* const observer = new IntersectionObserver(([entry]) => {
|
|
294
|
+
* if (entry?.isIntersecting) fetchNextPage()
|
|
295
|
+
* })
|
|
296
|
+
* observer.observe(sentinel)
|
|
297
|
+
*
|
|
298
|
+
* return () => observer.disconnect()
|
|
299
|
+
* }, [hasNextPage, isFetching, fetchNextPage])
|
|
300
|
+
*
|
|
301
|
+
* if (isPending) return 'Loading...'
|
|
302
|
+
* if (isError) return <span>Error: {error.message}</span>
|
|
303
|
+
*
|
|
304
|
+
* return (
|
|
305
|
+
* <>
|
|
306
|
+
* <ul>
|
|
307
|
+
* {data.pages.map((page) =>
|
|
308
|
+
* page.projects.map((project) => <li key={project.id}>{project.name}</li>),
|
|
309
|
+
* )}
|
|
310
|
+
* </ul>
|
|
311
|
+
* <div ref={sentinelRef}>{isFetchingNextPage ? 'Loading more...' : null}</div>
|
|
312
|
+
* </>
|
|
313
|
+
* )
|
|
314
|
+
* }
|
|
315
|
+
* ```
|
|
316
|
+
*
|
|
317
|
+
* @example
|
|
318
|
+
* A query that's disabled, type safe, until `postId` is set — pass `skipToken` as `queryFn`
|
|
319
|
+
* instead of setting `enabled: false`:
|
|
320
|
+
* ```tsx
|
|
321
|
+
* import { skipToken, useInfiniteQuery } from '@tanstack/preact-query'
|
|
322
|
+
*
|
|
323
|
+
* function Comments({ postId }: { postId: string | undefined }) {
|
|
324
|
+
* // Use `isLoading`, not `isPending`, so the loading state doesn't show while the query is disabled.
|
|
325
|
+
* const { data, isLoading, isError, error } = useInfiniteQuery({
|
|
326
|
+
* queryKey: ['post', postId, 'comments'],
|
|
327
|
+
* queryFn:
|
|
328
|
+
* postId != null
|
|
329
|
+
* ? ({ pageParam }) => fetchComments(postId, pageParam)
|
|
330
|
+
* : skipToken,
|
|
331
|
+
* initialPageParam: 0,
|
|
332
|
+
* getNextPageParam: (lastPage) => lastPage.nextId,
|
|
333
|
+
* })
|
|
334
|
+
*
|
|
335
|
+
* if (postId == null) return 'Select a post'
|
|
336
|
+
* if (isLoading) return 'Loading...'
|
|
337
|
+
* if (isError) return <span>Error: {error.message}</span>
|
|
338
|
+
*
|
|
160
339
|
* return (
|
|
161
|
-
* <
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
* >
|
|
165
|
-
* {isFetchingNextPage
|
|
166
|
-
* ? 'Loading more...'
|
|
167
|
-
* : hasNextPage
|
|
168
|
-
* ? 'Load More'
|
|
169
|
-
* : 'Nothing more to load'}
|
|
170
|
-
* </button>
|
|
340
|
+
* <ul>
|
|
341
|
+
* {data?.pages.map((page) => page.comments.map((c) => <li key={c.id}>{c.text}</li>))}
|
|
342
|
+
* </ul>
|
|
171
343
|
* )
|
|
172
344
|
* }
|
|
173
345
|
* ```
|
package/src/useIsFetching.ts
CHANGED
|
@@ -6,8 +6,8 @@ import { useQueryClient } from './QueryClientProvider'
|
|
|
6
6
|
import { useSyncExternalStore } from './utils'
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
-
* `useIsFetching`
|
|
10
|
-
*
|
|
9
|
+
* The `useIsFetching` hook returns the `number` of the queries that your application is loading or fetching in
|
|
10
|
+
* the background (useful for app-wide loading indicators).
|
|
11
11
|
*
|
|
12
12
|
* @param filters - The {@link QueryFilters} to narrow down the matched queries.
|
|
13
13
|
* @param queryClient - Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will
|
|
@@ -19,10 +19,12 @@ import { useSyncExternalStore } from './utils'
|
|
|
19
19
|
* ```tsx
|
|
20
20
|
* import { useIsFetching } from '@tanstack/preact-query'
|
|
21
21
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
22
|
+
* function PostsFetchingIndicator() {
|
|
23
|
+
* // How many queries matching the posts prefix are fetching?
|
|
24
|
+
* const isFetchingPosts = useIsFetching({ queryKey: ['posts'] })
|
|
25
|
+
*
|
|
26
|
+
* return isFetchingPosts ? <span>Refreshing posts...</span> : null
|
|
27
|
+
* }
|
|
26
28
|
* ```
|
|
27
29
|
*
|
|
28
30
|
* @example
|
package/src/useMutation.ts
CHANGED
|
@@ -21,14 +21,16 @@ import { useSyncExternalStore } from './utils'
|
|
|
21
21
|
* Unlike queries, mutations are typically used to create/update/delete data or perform server side-effects.
|
|
22
22
|
* `useMutation` is the hook for that.
|
|
23
23
|
*
|
|
24
|
-
* @see {@link mutationOptions} to share these options across multiple `useMutation` call sites
|
|
24
|
+
* @see {@link mutationOptions} to share these options across multiple `useMutation` call sites, or to look
|
|
25
|
+
* the mutation up elsewhere via its `mutationKey` (e.g. with `useMutationState`).
|
|
25
26
|
* @param options - The {@link UseMutationOptions} to use — everything you can pass to `useMutation`.
|
|
26
27
|
* @param queryClient - Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will
|
|
27
28
|
* be used.
|
|
28
29
|
* @returns `mutate`/`mutateAsync` also accept per-call `onSuccess`/`onError`/`onSettled` callbacks as a second
|
|
29
30
|
* argument, useful for triggering call-site side effects (e.g. navigation) without coupling them to the shared
|
|
30
|
-
* mutation definition.
|
|
31
|
-
* made
|
|
31
|
+
* mutation definition. Hook-level callbacks (passed to `options`) fire for every mutation; per-call callbacks
|
|
32
|
+
* fire only for the latest call you've made, and only while the component is still mounted — unmounting before
|
|
33
|
+
* the mutation settles removes the subscription and prevents them from firing.
|
|
32
34
|
*
|
|
33
35
|
* @example
|
|
34
36
|
* ```tsx
|
|
@@ -105,11 +107,11 @@ import { useSyncExternalStore } from './utils'
|
|
|
105
107
|
* newTodo,
|
|
106
108
|
* ])
|
|
107
109
|
*
|
|
108
|
-
* // Passed to `onError` as `
|
|
110
|
+
* // Passed to `onError` as `onMutateResult` if the mutation fails.
|
|
109
111
|
* return { previousTodos }
|
|
110
112
|
* },
|
|
111
|
-
* onError: (_err, _newTodo,
|
|
112
|
-
* queryClient.setQueryData(['todos'],
|
|
113
|
+
* onError: (_err, _newTodo, onMutateResult) => {
|
|
114
|
+
* queryClient.setQueryData(['todos'], onMutateResult?.previousTodos)
|
|
113
115
|
* },
|
|
114
116
|
* onSettled: () => {
|
|
115
117
|
* queryClient.invalidateQueries({ queryKey: ['todos'] })
|
|
@@ -124,7 +126,7 @@ import { useSyncExternalStore } from './utils'
|
|
|
124
126
|
*
|
|
125
127
|
* @example
|
|
126
128
|
* Callbacks passed per call to `mutate` only fire for the last call — `mutateAsync` gives you a
|
|
127
|
-
* promise per call instead, so you can wait for all of them:
|
|
129
|
+
* promise per call instead, so you can wait for all of them when they succeed:
|
|
128
130
|
* ```tsx
|
|
129
131
|
* import { useMutation, useQueryClient } from '@tanstack/preact-query'
|
|
130
132
|
*
|
|
@@ -168,13 +170,13 @@ import { useSyncExternalStore } from './utils'
|
|
|
168
170
|
* })
|
|
169
171
|
*
|
|
170
172
|
* async function handleAddAll(todos: Array<string>) {
|
|
171
|
-
* const
|
|
173
|
+
* const addResults = await Promise.allSettled(
|
|
172
174
|
* todos.map((todo) => addMutation.mutateAsync(todo)),
|
|
173
175
|
* )
|
|
174
176
|
*
|
|
175
|
-
*
|
|
176
|
-
* if (
|
|
177
|
-
* console.error(`Failed to add "${todos[index]}":`,
|
|
177
|
+
* addResults.forEach((addResult, index) => {
|
|
178
|
+
* if (addResult.status === 'rejected') {
|
|
179
|
+
* console.error(`Failed to add "${todos[index]}":`, addResult.reason)
|
|
178
180
|
* }
|
|
179
181
|
* })
|
|
180
182
|
* }
|