Skip to content

Commit 76e314d

Browse files
feat (QueryClient): getQueriesData for matching multiple queries (TanStack#2513)
1 parent 9ab60ac commit 76e314d

File tree

3 files changed

+94
-24
lines changed

3 files changed

+94
-24
lines changed

docs/src/pages/reference/QueryClient.md

Lines changed: 50 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -23,30 +23,31 @@ await queryClient.prefetchQuery('posts', fetchPosts)
2323

2424
Its available methods are:
2525

26-
- [`fetchQuery`](#queryclientfetchquery)
27-
- [`fetchInfiniteQuery`](#queryclientfetchinfinitequery)
28-
- [`prefetchQuery`](#queryclientprefetchquery)
29-
- [`prefetchInfiniteQuery`](#queryclientprefetchinfinitequery)
30-
- [`getQueryData`](#queryclientgetquerydata)
31-
- [`setQueryData`](#queryclientsetquerydata)
32-
- [`setQueriesData`](#queryclientsetqueriesdata)
33-
- [`getQueryState`](#queryclientgetquerystate)
34-
- [`invalidateQueries`](#queryclientinvalidatequeries)
35-
- [`refetchQueries`](#queryclientrefetchqueries)
36-
- [`cancelQueries`](#queryclientcancelqueries)
37-
- [`removeQueries`](#queryclientremovequeries)
38-
- [`resetQueries`](#queryclientresetqueries)
39-
- [`isFetching`](#queryclientisfetching)
40-
- [`isMutating`](#queryclientismutating)
41-
- [`getDefaultOptions`](#queryclientsetdefaultoptions)
42-
- [`setDefaultOptions`](#queryclientgetdefaultoptions)
43-
- [`getQueryDefaults`](#queryclientgetquerydefaults)
44-
- [`setQueryDefaults`](#queryclientsetquerydefaults)
45-
- [`getMutationDefaults`](#queryclientgetmutationdefaults)
46-
- [`setMutationDefaults`](#queryclientsetmutationdefaults)
47-
- [`getQueryCache`](#queryclientgetquerycache)
48-
- [`getMutationCache`](#queryclientgetmutationcache)
49-
- [`clear`](#queryclientclear)
26+
- [`queryClient.fetchQuery`](#queryclientfetchquery)
27+
- [`queryClient.fetchInfiniteQuery`](#queryclientfetchinfinitequery)
28+
- [`queryClient.prefetchQuery`](#queryclientprefetchquery)
29+
- [`queryClient.prefetchInfiniteQuery`](#queryclientprefetchinfinitequery)
30+
- [`queryClient.getQueryData`](#queryclientgetquerydata)
31+
- [`queryClient.getQueriesData`](#queryclientgetqueriesdata)
32+
- [`queryClient.setQueryData`](#queryclientsetquerydata)
33+
- [`queryClient.getQueryState`](#queryclientgetquerystate)
34+
- [`queryClient.setQueriesData`](#queryclientsetqueriesdata)
35+
- [`queryClient.invalidateQueries`](#queryclientinvalidatequeries)
36+
- [`queryClient.refetchQueries`](#queryclientrefetchqueries)
37+
- [`queryClient.cancelQueries`](#queryclientcancelqueries)
38+
- [`queryClient.removeQueries`](#queryclientremovequeries)
39+
- [`queryClient.resetQueries`](#queryclientresetqueries)
40+
- [`queryClient.isFetching`](#queryclientisfetching)
41+
- [`queryClient.isMutating`](#queryclientismutating)
42+
- [`queryClient.getDefaultOptions`](#queryclientgetdefaultoptions)
43+
- [`queryClient.setDefaultOptions`](#queryclientsetdefaultoptions)
44+
- [`queryClient.getQueryDefaults`](#queryclientgetquerydefaults)
45+
- [`queryClient.setQueryDefaults`](#queryclientsetquerydefaults)
46+
- [`queryClient.getMutationDefaults`](#queryclientgetmutationdefaults)
47+
- [`queryClient.setMutationDefaults`](#queryclientsetmutationdefaults)
48+
- [`queryClient.getQueryCache`](#queryclientgetquerycache)
49+
- [`queryClient.getMutationCache`](#queryclientgetmutationcache)
50+
- [`queryClient.clear`](#queryclientclear)
5051

5152
**Options**
5253

@@ -175,6 +176,31 @@ const data = queryClient.getQueryData(queryKey)
175176
- `data: TData | undefined`
176177
- The data for the cached query, or `undefined` if the query does not exist.
177178

179+
## `queryClient.getQueriesData`
180+
181+
`getQueriesData` is a synchronous function that can be used to get the cached data of multiple queries. Only queries that match the passed queryKey or queryFilter will be returned. If there are no matching queries, an empty array will be returned.
182+
183+
```js
184+
const data = queryClient.getQueriesData(queryKey | filters)
185+
```
186+
187+
**Options**
188+
189+
- `queryKey: QueryKey`: [Query Keys](../guides/query-keys) | `filters: QueryFilters`: [Query Filters](../guides/filters#query-filters)
190+
- if a queryKey is passed as the argument, the data with queryKeys fuzzily matching this param will be returned
191+
- if a filter is passed, the data with queryKeys matching the filter will be returned
192+
193+
**Returns**
194+
195+
- `[queryKey:QueryKey, data:TData | unknown][]`
196+
- An array of tuples for the matched query keys, or `[]` if there are no matches. The tuples are the query key and its associated data.
197+
198+
**Caveats**
199+
200+
Because the returned data in each tuple can be of varying structures (i.e. using a filter to return "active" queries can return different data types), the `TData` generic defaults to `unknown`. If you provide a more specific type to `TData` it is assumed that you are certain each tuple's data entry is all the same type.
201+
202+
This distinction is more a "convenience" for ts devs that know which structure will be returned.
203+
178204
## `queryClient.setQueryData`
179205

180206
`setQueryData` is a synchronous function that can be used to immediately update a query's cached data. If the query does not exist, it will be created. **If the query is not utilized by a query hook in the default `cacheTime` of 5 minutes, the query will be garbage collected**.

src/core/queryClient.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,19 @@ export class QueryClient {
111111
return this.queryCache.find<TData>(queryKey, filters)?.state.data
112112
}
113113

114+
getQueriesData<TData = unknown>(queryKey: QueryKey): [QueryKey, TData][]
115+
getQueriesData<TData = unknown>(filters: QueryFilters): [QueryKey, TData][]
116+
getQueriesData<TData = unknown>(
117+
queryKeyOrFilters: QueryKey | QueryFilters
118+
): [QueryKey, TData][] {
119+
return this.getQueryCache()
120+
.findAll(queryKeyOrFilters)
121+
.map(({ queryKey, state }) => {
122+
const data = state.data as TData
123+
return [queryKey, data]
124+
})
125+
}
126+
114127
setQueryData<TData>(
115128
queryKey: QueryKey,
116129
updater: Updater<TData | undefined, TData>,

src/core/tests/queryClient.test.tsx

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,37 @@ describe('queryClient', () => {
223223
})
224224
})
225225

226+
describe('getQueriesData', () => {
227+
test('should return the query data for all matched queries', () => {
228+
const key1 = queryKey()
229+
const key2 = queryKey()
230+
queryClient.setQueryData([key1, 1], 1)
231+
queryClient.setQueryData([key1, 2], 2)
232+
queryClient.setQueryData([key2, 2], 2)
233+
expect(queryClient.getQueriesData([key1])).toEqual([
234+
[[key1, 1], 1],
235+
[[key1, 2], 2],
236+
])
237+
})
238+
239+
test('should return empty array if queries are not found', () => {
240+
const key = queryKey()
241+
expect(queryClient.getQueriesData(key)).toEqual([])
242+
})
243+
244+
test('should accept query filters', () => {
245+
queryClient.setQueryData(['key', 1], 1)
246+
queryClient.setQueryData(['key', 2], 2)
247+
const query1 = queryCache.find(['key', 1])!
248+
249+
const result = queryClient.getQueriesData({
250+
predicate: query => query === query1,
251+
})
252+
253+
expect(result).toEqual([[['key', 1], 1]])
254+
})
255+
})
256+
226257
describe('fetchQuery', () => {
227258
test('should not type-error with strict query key', async () => {
228259
type StrictData = 'data'

0 commit comments

Comments
 (0)