Skip to content

Commit 6446a13

Browse files
committed
merge branch master
2 parents 513be09 + 418c48f commit 6446a13

File tree

13 files changed

+181
-35
lines changed

13 files changed

+181
-35
lines changed

docs/src/pages/guides/query-cancellation.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@ But don't worry! If your queries are high-bandwidth or potentially very expensiv
1414
## Using `axios`
1515

1616
```js
17-
import { CancelToken } from 'axios'
17+
import axios from 'axios'
1818

1919
const query = useQuery('todos', () => {
2020
// Create a new CancelToken source for this request
21+
const CancelToken = axios.CancelToken
2122
const source = CancelToken.source()
2223

2324
const promise = axios.get('/todos', {

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/queriesObserver.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ export class QueriesObserver extends Subscribable<QueriesObserverListener> {
8989
let hasIndexChange = false
9090

9191
const prevObservers = this.observers
92-
const prevOberversMap = this.observersMap
92+
const prevObserversMap = this.observersMap
9393

9494
const newResult: QueryObserverResult[] = []
9595
const newObservers: QueryObserver[] = []
@@ -102,7 +102,7 @@ export class QueriesObserver extends Subscribable<QueriesObserverListener> {
102102
const queryHash = defaultedOptions.queryHash!
103103
const observer = this.getObserver(defaultedOptions, i)
104104

105-
if (prevOberversMap[queryHash] || defaultedOptions.keepPreviousData) {
105+
if (prevObserversMap[queryHash] || defaultedOptions.keepPreviousData) {
106106
observer.setOptions(defaultedOptions, notifyOptions)
107107
}
108108

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/queryObserver.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ export class QueryObserver<
495495
if (
496496
typeof options.placeholderData !== 'undefined' &&
497497
typeof data === 'undefined' &&
498-
status === 'loading'
498+
(status === 'loading' || status === 'idle')
499499
) {
500500
let placeholderData
501501

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'

src/core/tests/queryObserver.test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -473,8 +473,8 @@ describe('queryObserver', () => {
473473
})
474474

475475
expect(observer.getCurrentResult()).toMatchObject({
476-
status: 'idle',
477-
data: undefined,
476+
status: 'success',
477+
data: 'placeholder',
478478
})
479479

480480
const results: QueryObserverResult<unknown>[] = []

src/core/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,7 @@ export interface MutationOptions<
481481
variables?: TVariables
482482
onMutate?: (
483483
variables: TVariables
484-
) => Promise<TContext> | Promise<undefined> | TContext | undefined
484+
) => Promise<TContext | undefined> | TContext | undefined
485485
onSuccess?: (
486486
data: TData,
487487
variables: TVariables,

src/core/utils.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,13 @@ export function parseFilterArgs<
166166
: [arg1 || {}, arg2]) as [TFilters, TOptions]
167167
}
168168

169+
export function parseMutationFilterArgs(
170+
arg1?: QueryKey | MutationFilters,
171+
arg2?: MutationFilters
172+
): MutationFilters | undefined {
173+
return isQueryKey(arg1) ? { ...arg2, mutationKey: arg1 } : arg1
174+
}
175+
169176
export function mapQueryStatusFilter(
170177
active?: boolean,
171178
inactive?: boolean

src/react/tests/useIsMutating.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ describe('useIsMutating', () => {
4545
const queryClient = new QueryClient()
4646

4747
function IsMutating() {
48-
const isMutating = useIsMutating({ mutationKey: 'mutation1' })
48+
const isMutating = useIsMutating('mutation1')
4949
isMutatings.push(isMutating)
5050
return null
5151
}

0 commit comments

Comments
 (0)