@tanstack/preact-query 5.102.4 → 5.102.6
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/QueryErrorResetBoundary.cjs +11 -9
- package/build/legacy/QueryErrorResetBoundary.cjs.map +1 -1
- package/build/legacy/QueryErrorResetBoundary.d.cts +11 -9
- package/build/legacy/QueryErrorResetBoundary.d.cts.map +1 -1
- package/build/legacy/QueryErrorResetBoundary.d.ts +11 -9
- package/build/legacy/QueryErrorResetBoundary.d.ts.map +1 -1
- package/build/legacy/QueryErrorResetBoundary.js +11 -9
- package/build/legacy/QueryErrorResetBoundary.js.map +1 -1
- package/build/legacy/useInfiniteQuery.cjs.map +1 -1
- package/build/legacy/useInfiniteQuery.d.cts +28 -24
- package/build/legacy/useInfiniteQuery.d.cts.map +1 -1
- package/build/legacy/useInfiniteQuery.d.ts +28 -24
- package/build/legacy/useInfiniteQuery.d.ts.map +1 -1
- package/build/legacy/useInfiniteQuery.js.map +1 -1
- package/build/legacy/useIsFetching.cjs +14 -0
- package/build/legacy/useIsFetching.cjs.map +1 -1
- package/build/legacy/useIsFetching.d.cts +14 -0
- package/build/legacy/useIsFetching.d.cts.map +1 -1
- package/build/legacy/useIsFetching.d.ts +14 -0
- package/build/legacy/useIsFetching.d.ts.map +1 -1
- package/build/legacy/useIsFetching.js +14 -0
- package/build/legacy/useIsFetching.js.map +1 -1
- package/build/legacy/useMutation.cjs +104 -1
- package/build/legacy/useMutation.cjs.map +1 -1
- package/build/legacy/useMutation.d.cts +104 -1
- package/build/legacy/useMutation.d.cts.map +1 -1
- package/build/legacy/useMutation.d.ts +104 -1
- package/build/legacy/useMutation.d.ts.map +1 -1
- package/build/legacy/useMutation.js +104 -1
- package/build/legacy/useMutation.js.map +1 -1
- package/build/legacy/useQuery.cjs.map +1 -1
- package/build/legacy/useQuery.d.cts +54 -2
- package/build/legacy/useQuery.d.cts.map +1 -1
- package/build/legacy/useQuery.d.ts +54 -2
- package/build/legacy/useQuery.d.ts.map +1 -1
- package/build/legacy/useQuery.js.map +1 -1
- package/build/legacy/useSuspenseInfiniteQuery.cjs +16 -8
- package/build/legacy/useSuspenseInfiniteQuery.cjs.map +1 -1
- package/build/legacy/useSuspenseInfiniteQuery.d.cts +16 -8
- package/build/legacy/useSuspenseInfiniteQuery.d.cts.map +1 -1
- package/build/legacy/useSuspenseInfiniteQuery.d.ts +16 -8
- package/build/legacy/useSuspenseInfiniteQuery.d.ts.map +1 -1
- package/build/legacy/useSuspenseInfiniteQuery.js +16 -8
- package/build/legacy/useSuspenseInfiniteQuery.js.map +1 -1
- package/build/legacy/useSuspenseQueries.cjs.map +1 -1
- package/build/legacy/useSuspenseQueries.d.cts +74 -6
- package/build/legacy/useSuspenseQueries.d.cts.map +1 -1
- package/build/legacy/useSuspenseQueries.d.ts +74 -6
- package/build/legacy/useSuspenseQueries.d.ts.map +1 -1
- package/build/legacy/useSuspenseQueries.js.map +1 -1
- package/build/legacy/useSuspenseQuery.cjs +4 -0
- package/build/legacy/useSuspenseQuery.cjs.map +1 -1
- package/build/legacy/useSuspenseQuery.d.cts +4 -0
- package/build/legacy/useSuspenseQuery.d.cts.map +1 -1
- package/build/legacy/useSuspenseQuery.d.ts +4 -0
- package/build/legacy/useSuspenseQuery.d.ts.map +1 -1
- package/build/legacy/useSuspenseQuery.js +4 -0
- package/build/legacy/useSuspenseQuery.js.map +1 -1
- package/build/modern/QueryErrorResetBoundary.cjs +11 -9
- package/build/modern/QueryErrorResetBoundary.cjs.map +1 -1
- package/build/modern/QueryErrorResetBoundary.d.cts +11 -9
- package/build/modern/QueryErrorResetBoundary.d.cts.map +1 -1
- package/build/modern/QueryErrorResetBoundary.d.ts +11 -9
- package/build/modern/QueryErrorResetBoundary.d.ts.map +1 -1
- package/build/modern/QueryErrorResetBoundary.js +11 -9
- package/build/modern/QueryErrorResetBoundary.js.map +1 -1
- package/build/modern/useInfiniteQuery.cjs.map +1 -1
- package/build/modern/useInfiniteQuery.d.cts +28 -24
- package/build/modern/useInfiniteQuery.d.cts.map +1 -1
- package/build/modern/useInfiniteQuery.d.ts +28 -24
- package/build/modern/useInfiniteQuery.d.ts.map +1 -1
- package/build/modern/useInfiniteQuery.js.map +1 -1
- package/build/modern/useIsFetching.cjs +14 -0
- package/build/modern/useIsFetching.cjs.map +1 -1
- package/build/modern/useIsFetching.d.cts +14 -0
- package/build/modern/useIsFetching.d.cts.map +1 -1
- package/build/modern/useIsFetching.d.ts +14 -0
- package/build/modern/useIsFetching.d.ts.map +1 -1
- package/build/modern/useIsFetching.js +14 -0
- package/build/modern/useIsFetching.js.map +1 -1
- package/build/modern/useMutation.cjs +104 -1
- package/build/modern/useMutation.cjs.map +1 -1
- package/build/modern/useMutation.d.cts +104 -1
- package/build/modern/useMutation.d.cts.map +1 -1
- package/build/modern/useMutation.d.ts +104 -1
- package/build/modern/useMutation.d.ts.map +1 -1
- package/build/modern/useMutation.js +104 -1
- package/build/modern/useMutation.js.map +1 -1
- package/build/modern/useQuery.cjs.map +1 -1
- package/build/modern/useQuery.d.cts +54 -2
- package/build/modern/useQuery.d.cts.map +1 -1
- package/build/modern/useQuery.d.ts +54 -2
- package/build/modern/useQuery.d.ts.map +1 -1
- package/build/modern/useQuery.js.map +1 -1
- package/build/modern/useSuspenseInfiniteQuery.cjs +16 -8
- package/build/modern/useSuspenseInfiniteQuery.cjs.map +1 -1
- package/build/modern/useSuspenseInfiniteQuery.d.cts +16 -8
- package/build/modern/useSuspenseInfiniteQuery.d.cts.map +1 -1
- package/build/modern/useSuspenseInfiniteQuery.d.ts +16 -8
- package/build/modern/useSuspenseInfiniteQuery.d.ts.map +1 -1
- package/build/modern/useSuspenseInfiniteQuery.js +16 -8
- package/build/modern/useSuspenseInfiniteQuery.js.map +1 -1
- package/build/modern/useSuspenseQueries.cjs.map +1 -1
- package/build/modern/useSuspenseQueries.d.cts +74 -6
- package/build/modern/useSuspenseQueries.d.cts.map +1 -1
- package/build/modern/useSuspenseQueries.d.ts +74 -6
- package/build/modern/useSuspenseQueries.d.ts.map +1 -1
- package/build/modern/useSuspenseQueries.js.map +1 -1
- package/build/modern/useSuspenseQuery.cjs +4 -0
- package/build/modern/useSuspenseQuery.cjs.map +1 -1
- package/build/modern/useSuspenseQuery.d.cts +4 -0
- package/build/modern/useSuspenseQuery.d.cts.map +1 -1
- package/build/modern/useSuspenseQuery.d.ts +4 -0
- package/build/modern/useSuspenseQuery.d.ts.map +1 -1
- package/build/modern/useSuspenseQuery.js +4 -0
- package/build/modern/useSuspenseQuery.js.map +1 -1
- package/package.json +3 -3
- package/src/QueryErrorResetBoundary.tsx +11 -9
- package/src/useInfiniteQuery.ts +28 -24
- package/src/useIsFetching.ts +14 -0
- package/src/useMutation.ts +104 -1
- package/src/useQuery.ts +54 -2
- package/src/useSuspenseInfiniteQuery.ts +16 -8
- package/src/useSuspenseQueries.ts +74 -6
- package/src/useSuspenseQuery.ts +4 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/preact-query",
|
|
3
|
-
"version": "5.102.
|
|
3
|
+
"version": "5.102.6",
|
|
4
4
|
"description": "Hooks for managing, caching and syncing asynchronous and remote data in preact",
|
|
5
5
|
"author": "tannerlinsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"!build/codemods/**/__tests__"
|
|
44
44
|
],
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@tanstack/query-core": "5.102.
|
|
46
|
+
"@tanstack/query-core": "5.102.6"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@preact/preset-vite": "^2.10.2",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"preact-render-to-string": "^6.6.4",
|
|
56
56
|
"typescript": "6.0.3",
|
|
57
57
|
"typescript-eslint": "^8.54.0",
|
|
58
|
-
"@tanstack/query-persist-client-core": "5.102.
|
|
58
|
+
"@tanstack/query-persist-client-core": "5.102.6",
|
|
59
59
|
"@tanstack/query-test-utils": "0.0.0"
|
|
60
60
|
},
|
|
61
61
|
"peerDependencies": {
|
|
@@ -143,15 +143,17 @@ export interface QueryErrorResetBoundaryProps {
|
|
|
143
143
|
* return children
|
|
144
144
|
* }
|
|
145
145
|
*
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
* <
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
*
|
|
146
|
+
* function App() {
|
|
147
|
+
* return (
|
|
148
|
+
* <QueryErrorResetBoundary>
|
|
149
|
+
* {({ reset }) => (
|
|
150
|
+
* <ErrorBoundary reset={reset}>
|
|
151
|
+
* <Page />
|
|
152
|
+
* </ErrorBoundary>
|
|
153
|
+
* )}
|
|
154
|
+
* </QueryErrorResetBoundary>
|
|
155
|
+
* )
|
|
156
|
+
* }
|
|
155
157
|
* ```
|
|
156
158
|
*/
|
|
157
159
|
export const QueryErrorResetBoundary = ({
|
package/src/useInfiniteQuery.ts
CHANGED
|
@@ -86,25 +86,27 @@ export function useInfiniteQuery<
|
|
|
86
86
|
*
|
|
87
87
|
* @example
|
|
88
88
|
* ```tsx
|
|
89
|
-
* import {
|
|
90
|
-
*
|
|
91
|
-
* const projectsOptions = infiniteQueryOptions({
|
|
92
|
-
* queryKey: ['projects'],
|
|
93
|
-
* queryFn: ({ pageParam }) => fetchProjects(pageParam),
|
|
94
|
-
* initialPageParam: 0,
|
|
95
|
-
* getNextPageParam: (lastPage) => lastPage.nextId,
|
|
96
|
-
* })
|
|
89
|
+
* import { useInfiniteQuery } from '@tanstack/preact-query'
|
|
97
90
|
*
|
|
98
91
|
* function Projects() {
|
|
99
|
-
* const { data, fetchNextPage, hasNextPage, isFetchingNextPage } =
|
|
100
|
-
* useInfiniteQuery(
|
|
92
|
+
* const { data, fetchNextPage, hasNextPage, isFetching, isFetchingNextPage } =
|
|
93
|
+
* useInfiniteQuery({
|
|
94
|
+
* queryKey: ['projects'],
|
|
95
|
+
* queryFn: ({ pageParam }) => fetchProjects(pageParam),
|
|
96
|
+
* initialPageParam: 0,
|
|
97
|
+
* getNextPageParam: (lastPage) => lastPage.nextId,
|
|
98
|
+
* })
|
|
101
99
|
*
|
|
102
100
|
* return (
|
|
103
101
|
* <button
|
|
104
102
|
* onClick={() => fetchNextPage()}
|
|
105
|
-
* disabled={!hasNextPage ||
|
|
103
|
+
* disabled={!hasNextPage || isFetching}
|
|
106
104
|
* >
|
|
107
|
-
*
|
|
105
|
+
* {isFetchingNextPage
|
|
106
|
+
* ? 'Loading more...'
|
|
107
|
+
* : hasNextPage
|
|
108
|
+
* ? 'Load More'
|
|
109
|
+
* : 'Nothing more to load'}
|
|
108
110
|
* </button>
|
|
109
111
|
* )
|
|
110
112
|
* }
|
|
@@ -144,25 +146,27 @@ export function useInfiniteQuery<
|
|
|
144
146
|
*
|
|
145
147
|
* @example
|
|
146
148
|
* ```tsx
|
|
147
|
-
* import {
|
|
148
|
-
*
|
|
149
|
-
* const projectsOptions = infiniteQueryOptions({
|
|
150
|
-
* queryKey: ['projects'],
|
|
151
|
-
* queryFn: ({ pageParam }) => fetchProjects(pageParam),
|
|
152
|
-
* initialPageParam: 0,
|
|
153
|
-
* getNextPageParam: (lastPage) => lastPage.nextId,
|
|
154
|
-
* })
|
|
149
|
+
* import { useInfiniteQuery } from '@tanstack/preact-query'
|
|
155
150
|
*
|
|
156
151
|
* function Projects() {
|
|
157
|
-
* const { data, fetchNextPage, hasNextPage, isFetchingNextPage } =
|
|
158
|
-
* useInfiniteQuery(
|
|
152
|
+
* const { data, fetchNextPage, hasNextPage, isFetching, isFetchingNextPage } =
|
|
153
|
+
* useInfiniteQuery({
|
|
154
|
+
* queryKey: ['projects'],
|
|
155
|
+
* queryFn: ({ pageParam }) => fetchProjects(pageParam),
|
|
156
|
+
* initialPageParam: 0,
|
|
157
|
+
* getNextPageParam: (lastPage) => lastPage.nextId,
|
|
158
|
+
* })
|
|
159
159
|
*
|
|
160
160
|
* return (
|
|
161
161
|
* <button
|
|
162
162
|
* onClick={() => fetchNextPage()}
|
|
163
|
-
* disabled={!hasNextPage ||
|
|
163
|
+
* disabled={!hasNextPage || isFetching}
|
|
164
164
|
* >
|
|
165
|
-
*
|
|
165
|
+
* {isFetchingNextPage
|
|
166
|
+
* ? 'Loading more...'
|
|
167
|
+
* : hasNextPage
|
|
168
|
+
* ? 'Load More'
|
|
169
|
+
* : 'Nothing more to load'}
|
|
166
170
|
* </button>
|
|
167
171
|
* )
|
|
168
172
|
* }
|
package/src/useIsFetching.ts
CHANGED
|
@@ -24,6 +24,20 @@ import { useSyncExternalStore } from './utils'
|
|
|
24
24
|
* // How many queries matching the posts prefix are fetching?
|
|
25
25
|
* const isFetchingPosts = useIsFetching({ queryKey: ['posts'] })
|
|
26
26
|
* ```
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* A global loading indicator for any query fetching in the background, not just the ones on screen:
|
|
30
|
+
* ```tsx
|
|
31
|
+
* import { useIsFetching } from '@tanstack/preact-query'
|
|
32
|
+
*
|
|
33
|
+
* function GlobalLoadingIndicator() {
|
|
34
|
+
* const isFetching = useIsFetching()
|
|
35
|
+
*
|
|
36
|
+
* return isFetching ? (
|
|
37
|
+
* <div>Queries are fetching in the background...</div>
|
|
38
|
+
* ) : null
|
|
39
|
+
* }
|
|
40
|
+
* ```
|
|
27
41
|
*/
|
|
28
42
|
export function useIsFetching(
|
|
29
43
|
filters?: QueryFilters,
|
package/src/useMutation.ts
CHANGED
|
@@ -43,7 +43,45 @@ import { useSyncExternalStore } from './utils'
|
|
|
43
43
|
* })
|
|
44
44
|
*
|
|
45
45
|
* return (
|
|
46
|
-
* <button
|
|
46
|
+
* <button
|
|
47
|
+
* onClick={() =>
|
|
48
|
+
* addMutation.mutate('Item', {
|
|
49
|
+
* onError: (error) => console.error('Failed to add item:', error),
|
|
50
|
+
* })
|
|
51
|
+
* }
|
|
52
|
+
* >
|
|
53
|
+
* Add
|
|
54
|
+
* </button>
|
|
55
|
+
* )
|
|
56
|
+
* }
|
|
57
|
+
* ```
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* Rendering the mutation's own state, rather than just firing it off:
|
|
61
|
+
* ```tsx
|
|
62
|
+
* import { useMutation, useQueryClient } from '@tanstack/preact-query'
|
|
63
|
+
*
|
|
64
|
+
* function AddTodo() {
|
|
65
|
+
* const queryClient = useQueryClient()
|
|
66
|
+
*
|
|
67
|
+
* const addMutation = useMutation({
|
|
68
|
+
* mutationFn: addTodo,
|
|
69
|
+
* onSuccess: () => queryClient.invalidateQueries({ queryKey: ['todos'] }),
|
|
70
|
+
* })
|
|
71
|
+
*
|
|
72
|
+
* return (
|
|
73
|
+
* <div>
|
|
74
|
+
* {addMutation.isPending ? (
|
|
75
|
+
* 'Adding todo...'
|
|
76
|
+
* ) : (
|
|
77
|
+
* <>
|
|
78
|
+
* {addMutation.isError ? (
|
|
79
|
+
* <div>An error occurred: {addMutation.error.message}</div>
|
|
80
|
+
* ) : null}
|
|
81
|
+
* <button onClick={() => addMutation.mutate('Item')}>Add</button>
|
|
82
|
+
* </>
|
|
83
|
+
* )}
|
|
84
|
+
* </div>
|
|
47
85
|
* )
|
|
48
86
|
* }
|
|
49
87
|
* ```
|
|
@@ -83,6 +121,71 @@ import { useSyncExternalStore } from './utils'
|
|
|
83
121
|
* )
|
|
84
122
|
* }
|
|
85
123
|
* ```
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* 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:
|
|
128
|
+
* ```tsx
|
|
129
|
+
* import { useMutation, useQueryClient } from '@tanstack/preact-query'
|
|
130
|
+
*
|
|
131
|
+
* function AddTodos() {
|
|
132
|
+
* const queryClient = useQueryClient()
|
|
133
|
+
*
|
|
134
|
+
* const addMutation = useMutation({
|
|
135
|
+
* mutationFn: addTodo,
|
|
136
|
+
* onSuccess: () => queryClient.invalidateQueries({ queryKey: ['todos'] }),
|
|
137
|
+
* })
|
|
138
|
+
*
|
|
139
|
+
* async function handleAddAll(todos: Array<string>) {
|
|
140
|
+
* try {
|
|
141
|
+
* await Promise.all(todos.map((todo) => addMutation.mutateAsync(todo)))
|
|
142
|
+
* } catch (error) {
|
|
143
|
+
* console.error('Failed to add todos:', error)
|
|
144
|
+
* }
|
|
145
|
+
* }
|
|
146
|
+
*
|
|
147
|
+
* return (
|
|
148
|
+
* <button onClick={() => handleAddAll(['Todo 1', 'Todo 2', 'Todo 3'])}>
|
|
149
|
+
* Add all
|
|
150
|
+
* </button>
|
|
151
|
+
* )
|
|
152
|
+
* }
|
|
153
|
+
* ```
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* If some of the mutations above can fail independently of the others, and you want to know which ones
|
|
157
|
+
* did — rather than losing that information the moment the first one rejects — swap `Promise.all` for
|
|
158
|
+
* `Promise.allSettled`:
|
|
159
|
+
* ```tsx
|
|
160
|
+
* import { useMutation, useQueryClient } from '@tanstack/preact-query'
|
|
161
|
+
*
|
|
162
|
+
* function AddTodos() {
|
|
163
|
+
* const queryClient = useQueryClient()
|
|
164
|
+
*
|
|
165
|
+
* const addMutation = useMutation({
|
|
166
|
+
* mutationFn: addTodo,
|
|
167
|
+
* onSuccess: () => queryClient.invalidateQueries({ queryKey: ['todos'] }),
|
|
168
|
+
* })
|
|
169
|
+
*
|
|
170
|
+
* async function handleAddAll(todos: Array<string>) {
|
|
171
|
+
* const results = await Promise.allSettled(
|
|
172
|
+
* todos.map((todo) => addMutation.mutateAsync(todo)),
|
|
173
|
+
* )
|
|
174
|
+
*
|
|
175
|
+
* results.forEach((result, index) => {
|
|
176
|
+
* if (result.status === 'rejected') {
|
|
177
|
+
* console.error(`Failed to add "${todos[index]}":`, result.reason)
|
|
178
|
+
* }
|
|
179
|
+
* })
|
|
180
|
+
* }
|
|
181
|
+
*
|
|
182
|
+
* return (
|
|
183
|
+
* <button onClick={() => handleAddAll(['Todo 1', 'Todo 2', 'Todo 3'])}>
|
|
184
|
+
* Add all
|
|
185
|
+
* </button>
|
|
186
|
+
* )
|
|
187
|
+
* }
|
|
188
|
+
* ```
|
|
86
189
|
*/
|
|
87
190
|
export function useMutation<
|
|
88
191
|
TData = unknown,
|
package/src/useQuery.ts
CHANGED
|
@@ -83,6 +83,24 @@ export function useQuery<
|
|
|
83
83
|
* )
|
|
84
84
|
* }
|
|
85
85
|
* ```
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* The same query, checking `isPending`/`isError` instead of `status` — pick whichever reads better to you:
|
|
89
|
+
* ```tsx
|
|
90
|
+
* import { useQuery } from '@tanstack/preact-query'
|
|
91
|
+
*
|
|
92
|
+
* function Posts() {
|
|
93
|
+
* const { isPending, isError, data, error } = useQuery({
|
|
94
|
+
* queryKey: ['posts'],
|
|
95
|
+
* queryFn: fetchPosts,
|
|
96
|
+
* })
|
|
97
|
+
*
|
|
98
|
+
* if (isPending) return 'Loading...'
|
|
99
|
+
* if (isError) return <span>Error: {error.message}</span>
|
|
100
|
+
*
|
|
101
|
+
* return <>{data.map((post) => <p key={post.id}>{post.title}</p>)}</>
|
|
102
|
+
* }
|
|
103
|
+
* ```
|
|
86
104
|
*/
|
|
87
105
|
export function useQuery<
|
|
88
106
|
TQueryFnData = unknown,
|
|
@@ -130,17 +148,22 @@ export function useQuery<
|
|
|
130
148
|
* ```
|
|
131
149
|
*
|
|
132
150
|
* @example
|
|
133
|
-
* A dependent query, only enabled once `postId` is set
|
|
151
|
+
* A dependent query, only enabled once `postId` is set — use `isLoading`, not `isPending`, so the
|
|
152
|
+
* loading state doesn't show while the query is disabled:
|
|
134
153
|
* ```tsx
|
|
135
154
|
* import { useQuery } from '@tanstack/preact-query'
|
|
136
155
|
*
|
|
137
156
|
* function Post({ postId }: { postId: number | undefined }) {
|
|
138
|
-
* const { data } = useQuery({
|
|
157
|
+
* const { data, isLoading, isError, error } = useQuery({
|
|
139
158
|
* queryKey: ['post', postId],
|
|
140
159
|
* queryFn: () => fetchPost(postId!),
|
|
141
160
|
* enabled: postId != null,
|
|
142
161
|
* })
|
|
143
162
|
*
|
|
163
|
+
* if (postId == null) return 'Select a post'
|
|
164
|
+
* if (isLoading) return 'Loading...'
|
|
165
|
+
* if (isError) return <span>Error: {error.message}</span>
|
|
166
|
+
*
|
|
144
167
|
* return <h1>{data?.title}</h1>
|
|
145
168
|
* }
|
|
146
169
|
* ```
|
|
@@ -165,6 +188,35 @@ export function useQuery<
|
|
|
165
188
|
* return <h1>{data?.title}</h1>
|
|
166
189
|
* }
|
|
167
190
|
* ```
|
|
191
|
+
*
|
|
192
|
+
* @example
|
|
193
|
+
* Paginated data, keeping the previous page's data visible while the next page loads:
|
|
194
|
+
* ```tsx
|
|
195
|
+
* import { keepPreviousData, useQuery } from '@tanstack/preact-query'
|
|
196
|
+
* import { useState } from 'preact/hooks'
|
|
197
|
+
*
|
|
198
|
+
* function Posts() {
|
|
199
|
+
* const [page, setPage] = useState(0)
|
|
200
|
+
*
|
|
201
|
+
* const { data, isPlaceholderData } = useQuery({
|
|
202
|
+
* queryKey: ['posts', page],
|
|
203
|
+
* queryFn: () => fetchPosts(page),
|
|
204
|
+
* placeholderData: keepPreviousData,
|
|
205
|
+
* })
|
|
206
|
+
*
|
|
207
|
+
* return (
|
|
208
|
+
* <div>
|
|
209
|
+
* {data?.map((post) => <p key={post.id}>{post.title}</p>)}
|
|
210
|
+
* <button
|
|
211
|
+
* disabled={isPlaceholderData}
|
|
212
|
+
* onClick={() => setPage((old) => old + 1)}
|
|
213
|
+
* >
|
|
214
|
+
* Next Page
|
|
215
|
+
* </button>
|
|
216
|
+
* </div>
|
|
217
|
+
* )
|
|
218
|
+
* }
|
|
219
|
+
* ```
|
|
168
220
|
*/
|
|
169
221
|
export function useQuery<
|
|
170
222
|
TQueryFnData = unknown,
|
|
@@ -35,20 +35,28 @@ import { useBaseQuery } from './useBaseQuery'
|
|
|
35
35
|
*
|
|
36
36
|
* function Projects() {
|
|
37
37
|
* // `data` is guaranteed to be defined here — no `isPending` check needed.
|
|
38
|
-
* const { data, fetchNextPage, hasNextPage } =
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
38
|
+
* const { data, fetchNextPage, hasNextPage, isFetching, isFetchingNextPage } =
|
|
39
|
+
* useSuspenseInfiniteQuery({
|
|
40
|
+
* queryKey: ['projects'],
|
|
41
|
+
* queryFn: ({ pageParam }) => fetchProjects(pageParam),
|
|
42
|
+
* initialPageParam: 0,
|
|
43
|
+
* getNextPageParam: (lastPage) => lastPage.nextId,
|
|
44
|
+
* })
|
|
44
45
|
*
|
|
45
46
|
* return (
|
|
46
47
|
* <div>
|
|
47
48
|
* {data.pages.map((page) =>
|
|
48
49
|
* page.projects.map((project) => <p key={project.id}>{project.name}</p>),
|
|
49
50
|
* )}
|
|
50
|
-
* <button
|
|
51
|
-
*
|
|
51
|
+
* <button
|
|
52
|
+
* onClick={() => fetchNextPage()}
|
|
53
|
+
* disabled={!hasNextPage || isFetching}
|
|
54
|
+
* >
|
|
55
|
+
* {isFetchingNextPage
|
|
56
|
+
* ? 'Loading more...'
|
|
57
|
+
* : hasNextPage
|
|
58
|
+
* ? 'Load More'
|
|
59
|
+
* : 'Nothing more to load'}
|
|
52
60
|
* </button>
|
|
53
61
|
* </div>
|
|
54
62
|
* )
|
|
@@ -202,7 +202,7 @@ export type SuspenseQueriesResults<
|
|
|
202
202
|
*
|
|
203
203
|
* function Posts({ ids }: { ids: Array<number> }) {
|
|
204
204
|
* // Every result is guaranteed to be defined — no per-query `isPending` check needed.
|
|
205
|
-
* const
|
|
205
|
+
* const postQueries = useSuspenseQueries({
|
|
206
206
|
* queries: ids.map((id) => ({
|
|
207
207
|
* queryKey: ['post', id],
|
|
208
208
|
* queryFn: () => fetchPost(id),
|
|
@@ -211,8 +211,8 @@ export type SuspenseQueriesResults<
|
|
|
211
211
|
*
|
|
212
212
|
* return (
|
|
213
213
|
* <ul>
|
|
214
|
-
* {
|
|
215
|
-
* <li key={
|
|
214
|
+
* {postQueries.map((query) => (
|
|
215
|
+
* <li key={query.data.id}>{query.data.title}</li>
|
|
216
216
|
* ))}
|
|
217
217
|
* </ul>
|
|
218
218
|
* )
|
|
@@ -226,6 +226,40 @@ export type SuspenseQueriesResults<
|
|
|
226
226
|
* )
|
|
227
227
|
* }
|
|
228
228
|
* ```
|
|
229
|
+
*
|
|
230
|
+
* @example
|
|
231
|
+
* Several different queries — use `useSuspenseQueries` instead of multiple `useSuspenseQuery` calls, so
|
|
232
|
+
* they fetch in parallel rather than suspending one after another:
|
|
233
|
+
* ```tsx
|
|
234
|
+
* import { Suspense } from 'preact/compat'
|
|
235
|
+
* import { useSuspenseQueries } from '@tanstack/preact-query'
|
|
236
|
+
*
|
|
237
|
+
* function Dashboard() {
|
|
238
|
+
* const [usersQuery, teamsQuery, projectsQuery] = useSuspenseQueries({
|
|
239
|
+
* queries: [
|
|
240
|
+
* { queryKey: ['users'], queryFn: fetchUsers },
|
|
241
|
+
* { queryKey: ['teams'], queryFn: fetchTeams },
|
|
242
|
+
* { queryKey: ['projects'], queryFn: fetchProjects },
|
|
243
|
+
* ],
|
|
244
|
+
* })
|
|
245
|
+
*
|
|
246
|
+
* return (
|
|
247
|
+
* <div>
|
|
248
|
+
* <UserList users={usersQuery.data} />
|
|
249
|
+
* <TeamList teams={teamsQuery.data} />
|
|
250
|
+
* <ProjectList projects={projectsQuery.data} />
|
|
251
|
+
* </div>
|
|
252
|
+
* )
|
|
253
|
+
* }
|
|
254
|
+
*
|
|
255
|
+
* function App() {
|
|
256
|
+
* return (
|
|
257
|
+
* <Suspense fallback={<h1>Loading dashboard...</h1>}>
|
|
258
|
+
* <Dashboard />
|
|
259
|
+
* </Suspense>
|
|
260
|
+
* )
|
|
261
|
+
* }
|
|
262
|
+
* ```
|
|
229
263
|
*/
|
|
230
264
|
export function useSuspenseQueries<
|
|
231
265
|
T extends Array<any>,
|
|
@@ -269,7 +303,7 @@ export function useSuspenseQueries<
|
|
|
269
303
|
*
|
|
270
304
|
* function Posts({ ids }: { ids: Array<number> }) {
|
|
271
305
|
* // Every result is guaranteed to be defined — no per-query `isPending` check needed.
|
|
272
|
-
* const
|
|
306
|
+
* const postQueries = useSuspenseQueries({
|
|
273
307
|
* queries: ids.map((id) => ({
|
|
274
308
|
* queryKey: ['post', id],
|
|
275
309
|
* queryFn: () => fetchPost(id),
|
|
@@ -278,8 +312,8 @@ export function useSuspenseQueries<
|
|
|
278
312
|
*
|
|
279
313
|
* return (
|
|
280
314
|
* <ul>
|
|
281
|
-
* {
|
|
282
|
-
* <li key={
|
|
315
|
+
* {postQueries.map((query) => (
|
|
316
|
+
* <li key={query.data.id}>{query.data.title}</li>
|
|
283
317
|
* ))}
|
|
284
318
|
* </ul>
|
|
285
319
|
* )
|
|
@@ -293,6 +327,40 @@ export function useSuspenseQueries<
|
|
|
293
327
|
* )
|
|
294
328
|
* }
|
|
295
329
|
* ```
|
|
330
|
+
*
|
|
331
|
+
* @example
|
|
332
|
+
* Several different queries — use `useSuspenseQueries` instead of multiple `useSuspenseQuery` calls, so
|
|
333
|
+
* they fetch in parallel rather than suspending one after another:
|
|
334
|
+
* ```tsx
|
|
335
|
+
* import { Suspense } from 'preact/compat'
|
|
336
|
+
* import { useSuspenseQueries } from '@tanstack/preact-query'
|
|
337
|
+
*
|
|
338
|
+
* function Dashboard() {
|
|
339
|
+
* const [usersQuery, teamsQuery, projectsQuery] = useSuspenseQueries({
|
|
340
|
+
* queries: [
|
|
341
|
+
* { queryKey: ['users'], queryFn: fetchUsers },
|
|
342
|
+
* { queryKey: ['teams'], queryFn: fetchTeams },
|
|
343
|
+
* { queryKey: ['projects'], queryFn: fetchProjects },
|
|
344
|
+
* ],
|
|
345
|
+
* })
|
|
346
|
+
*
|
|
347
|
+
* return (
|
|
348
|
+
* <div>
|
|
349
|
+
* <UserList users={usersQuery.data} />
|
|
350
|
+
* <TeamList teams={teamsQuery.data} />
|
|
351
|
+
* <ProjectList projects={projectsQuery.data} />
|
|
352
|
+
* </div>
|
|
353
|
+
* )
|
|
354
|
+
* }
|
|
355
|
+
*
|
|
356
|
+
* function App() {
|
|
357
|
+
* return (
|
|
358
|
+
* <Suspense fallback={<h1>Loading dashboard...</h1>}>
|
|
359
|
+
* <Dashboard />
|
|
360
|
+
* </Suspense>
|
|
361
|
+
* )
|
|
362
|
+
* }
|
|
363
|
+
* ```
|
|
296
364
|
*/
|
|
297
365
|
export function useSuspenseQueries<
|
|
298
366
|
T extends Array<any>,
|
package/src/useSuspenseQuery.ts
CHANGED
|
@@ -11,6 +11,10 @@ import { useBaseQuery } from './useBaseQuery'
|
|
|
11
11
|
*
|
|
12
12
|
* Caveat: cancellation does not work.
|
|
13
13
|
*
|
|
14
|
+
* @remarks Multiple `useSuspenseQuery` calls in the same component suspend serially, causing a request
|
|
15
|
+
* waterfall — each one blocks rendering until it resolves, so the next doesn't even start fetching until then.
|
|
16
|
+
* Use {@link useSuspenseQueries} instead when you have more than one suspenseful query in a component, so they
|
|
17
|
+
* fetch in parallel.
|
|
14
18
|
* @param options - The {@link UseSuspenseQueryOptions} to use — the same options as `useQuery`, minus the ones listed above.
|
|
15
19
|
* @param queryClient - Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will
|
|
16
20
|
* be used.
|