From 48b35bb2498796a261393f478c2209596c3d546b Mon Sep 17 00:00:00 2001 From: Dominik Dorfmeister Date: Sat, 13 Nov 2021 18:13:44 +0100 Subject: [PATCH 1/5] feat: better query filters use a tri-state enum (active / inactive / all) to indicate which queries to match. It usually doesn't make sense to match no queries ("none"); However, for `refetch` on `invalidateQueries`, we can say we want to invalidate some queries, but refetch none of them. Since the default is to refetch all active queries, we need a way to override that. So `none` is allowed there --- src/core/queryClient.ts | 18 +++---- src/core/tests/queriesObserver.test.tsx | 8 ++-- src/core/tests/queryCache.test.tsx | 18 +++---- src/core/tests/queryClient.test.tsx | 62 +++++-------------------- src/core/tests/utils.test.tsx | 21 --------- src/core/types.ts | 5 +- src/core/utils.ts | 49 +++---------------- 7 files changed, 42 insertions(+), 139 deletions(-) diff --git a/src/core/queryClient.ts b/src/core/queryClient.ts index cb9d6ba181..fe933604b6 100644 --- a/src/core/queryClient.ts +++ b/src/core/queryClient.ts @@ -203,8 +203,8 @@ export class QueryClient { const queryCache = this.queryCache const refetchFilters: RefetchQueryFilters = { + type: 'active', ...filters, - active: true, } return notifyManager.batch(() => { @@ -255,18 +255,18 @@ export class QueryClient { ): Promise { const [filters, options] = parseFilterArgs(arg1, arg2, arg3) - const refetchFilters: RefetchQueryFilters = { - ...filters, - // if filters.refetchActive is not provided and filters.active is explicitly false, - // e.g. invalidateQueries({ active: false }), we don't want to refetch active queries - active: filters.refetchActive ?? filters.active ?? true, - inactive: filters.refetchInactive ?? false, - } - return notifyManager.batch(() => { this.queryCache.findAll(filters).forEach(query => { query.invalidate() }) + + if (filters?.refetch === 'none') { + return Promise.resolve() + } + const refetchFilters: RefetchQueryFilters = { + ...filters, + type: filters?.refetch ?? filters?.type ?? 'active', + } return this.refetchQueries(refetchFilters, options) }) } diff --git a/src/core/tests/queriesObserver.test.tsx b/src/core/tests/queriesObserver.test.tsx index 8aca223332..9b0a7535e9 100644 --- a/src/core/tests/queriesObserver.test.tsx +++ b/src/core/tests/queriesObserver.test.tsx @@ -101,11 +101,11 @@ describe('queriesObserver', () => { observer.setQueries([{ queryKey: key2, queryFn: queryFn2 }]) await sleep(1) const queryCache = queryClient.getQueryCache() - expect(queryCache.find(key1, { active: true })).toBeUndefined() - expect(queryCache.find(key2, { active: true })).toBeDefined() + expect(queryCache.find(key1, { type: 'active' })).toBeUndefined() + expect(queryCache.find(key2, { type: 'active' })).toBeDefined() unsubscribe() - expect(queryCache.find(key1, { active: true })).toBeUndefined() - expect(queryCache.find(key2, { active: true })).toBeUndefined() + expect(queryCache.find(key1, { type: 'active' })).toBeUndefined() + expect(queryCache.find(key2, { type: 'active' })).toBeUndefined() expect(results.length).toBe(6) expect(results[0]).toMatchObject([ { status: 'idle', data: undefined }, diff --git a/src/core/tests/queryCache.test.tsx b/src/core/tests/queryCache.test.tsx index cf26eb3ef7..4a17d2d0a0 100644 --- a/src/core/tests/queryCache.test.tsx +++ b/src/core/tests/queryCache.test.tsx @@ -92,20 +92,20 @@ describe('queryCache', () => { expect(queryCache.findAll([key1])).toEqual([query1]) expect(queryCache.findAll()).toEqual([query1, query2, query3, query4]) expect(queryCache.findAll({})).toEqual([query1, query2, query3, query4]) - expect(queryCache.findAll(key1, { active: false })).toEqual([query1]) - expect(queryCache.findAll(key1, { active: true })).toEqual([]) + expect(queryCache.findAll(key1, { type: 'inactive' })).toEqual([query1]) + expect(queryCache.findAll(key1, { type: 'active' })).toEqual([]) expect(queryCache.findAll(key1, { stale: true })).toEqual([]) expect(queryCache.findAll(key1, { stale: false })).toEqual([query1]) - expect(queryCache.findAll(key1, { stale: false, active: true })).toEqual( - [] - ) expect( - queryCache.findAll(key1, { stale: false, active: false }) + queryCache.findAll(key1, { stale: false, type: 'active' }) + ).toEqual([]) + expect( + queryCache.findAll(key1, { stale: false, type: 'inactive' }) ).toEqual([query1]) expect( queryCache.findAll(key1, { stale: false, - active: false, + type: 'inactive', exact: true, }) ).toEqual([query1]) @@ -128,8 +128,8 @@ describe('queryCache', () => { query3, ]) expect(queryCache.findAll([{ a: 'a' }], { stale: true })).toEqual([]) - expect(queryCache.findAll([{ a: 'a' }], { active: true })).toEqual([]) - expect(queryCache.findAll([{ a: 'a' }], { inactive: true })).toEqual([ + expect(queryCache.findAll([{ a: 'a' }], { type: 'active' })).toEqual([]) + expect(queryCache.findAll([{ a: 'a' }], { type: 'inactive' })).toEqual([ query3, ]) expect( diff --git a/src/core/tests/queryClient.test.tsx b/src/core/tests/queryClient.test.tsx index 5e0ee089a1..2c1593f10e 100644 --- a/src/core/tests/queryClient.test.tsx +++ b/src/core/tests/queryClient.test.tsx @@ -673,7 +673,7 @@ describe('queryClient', () => { staleTime: Infinity, }) const unsubscribe = observer.subscribe() - await queryClient.refetchQueries({ active: true, stale: false }) + await queryClient.refetchQueries({ type: 'active', stale: false }) unsubscribe() expect(queryFn1).toHaveBeenCalledTimes(2) expect(queryFn2).toHaveBeenCalledTimes(1) @@ -711,7 +711,7 @@ describe('queryClient', () => { queryFn: queryFn1, }) const unsubscribe = observer.subscribe() - await queryClient.refetchQueries({ active: true, stale: true }) + await queryClient.refetchQueries({ type: 'active', stale: true }) unsubscribe() expect(queryFn1).toHaveBeenCalledTimes(2) expect(queryFn2).toHaveBeenCalledTimes(1) @@ -749,7 +749,7 @@ describe('queryClient', () => { staleTime: Infinity, }) const unsubscribe = observer.subscribe() - await queryClient.refetchQueries({ active: true, inactive: true }) + await queryClient.refetchQueries({ type: 'all' }) unsubscribe() expect(queryFn1).toHaveBeenCalledTimes(2) expect(queryFn2).toHaveBeenCalledTimes(2) @@ -768,7 +768,7 @@ describe('queryClient', () => { staleTime: Infinity, }) const unsubscribe = observer.subscribe() - await queryClient.refetchQueries({ active: true }) + await queryClient.refetchQueries({ type: 'active' }) unsubscribe() expect(queryFn1).toHaveBeenCalledTimes(2) expect(queryFn2).toHaveBeenCalledTimes(1) @@ -787,31 +787,12 @@ describe('queryClient', () => { staleTime: Infinity, }) const unsubscribe = observer.subscribe() - await queryClient.refetchQueries({ inactive: true }) + await queryClient.refetchQueries({ type: 'inactive' }) unsubscribe() expect(queryFn1).toHaveBeenCalledTimes(1) expect(queryFn2).toHaveBeenCalledTimes(2) }) - test('should skip refetch for all active and inactive queries', async () => { - const key1 = queryKey() - const key2 = queryKey() - const queryFn1 = jest.fn() - const queryFn2 = jest.fn() - await queryClient.fetchQuery(key1, queryFn1) - await queryClient.fetchQuery(key2, queryFn2) - const observer = new QueryObserver(queryClient, { - queryKey: key1, - queryFn: queryFn1, - staleTime: Infinity, - }) - const unsubscribe = observer.subscribe() - await queryClient.refetchQueries({ active: false, inactive: false }) - unsubscribe() - expect(queryFn1).toHaveBeenCalledTimes(1) - expect(queryFn2).toHaveBeenCalledTimes(1) - }) - test('should throw an error if throwOnError option is set to true', async () => { const consoleMock = mockConsoleError() const key1 = queryKey() @@ -876,7 +857,7 @@ describe('queryClient', () => { expect(queryFn2).toHaveBeenCalledTimes(1) }) - test('should not refetch active queries when "refetchActive" is false', async () => { + test('should not refetch active queries when "refetch" is "none"', async () => { const key1 = queryKey() const key2 = queryKey() const queryFn1 = jest.fn() @@ -890,14 +871,14 @@ describe('queryClient', () => { }) const unsubscribe = observer.subscribe() queryClient.invalidateQueries(key1, { - refetchActive: false, + refetch: 'none', }) unsubscribe() expect(queryFn1).toHaveBeenCalledTimes(1) expect(queryFn2).toHaveBeenCalledTimes(1) }) - test('should refetch inactive queries when "refetchInactive" is true', async () => { + test('should refetch inactive queries and active queries when "refetch" is "all"', async () => { const key1 = queryKey() const key2 = queryKey() const queryFn1 = jest.fn() @@ -912,34 +893,13 @@ describe('queryClient', () => { }) const unsubscribe = observer.subscribe() queryClient.invalidateQueries(key1, { - refetchInactive: true, + refetch: 'all', }) unsubscribe() expect(queryFn1).toHaveBeenCalledTimes(2) expect(queryFn2).toHaveBeenCalledTimes(1) }) - test('should not refetch active queries when "refetchActive" is not provided and "active" is false', async () => { - const key1 = queryKey() - const key2 = queryKey() - const queryFn1 = jest.fn() - const queryFn2 = jest.fn() - await queryClient.fetchQuery(key1, queryFn1) - await queryClient.fetchQuery(key2, queryFn2) - const observer = new QueryObserver(queryClient, { - queryKey: key1, - queryFn: queryFn1, - staleTime: Infinity, - }) - const unsubscribe = observer.subscribe() - queryClient.invalidateQueries(key1, { - active: false, - }) - unsubscribe() - expect(queryFn1).toHaveBeenCalledTimes(1) - expect(queryFn2).toHaveBeenCalledTimes(1) - }) - test('should cancel ongoing fetches if cancelRefetch option is passed', async () => { const key = queryKey() const cancelFn = jest.fn() @@ -1089,7 +1049,7 @@ describe('queryClient', () => { await queryClient.invalidateQueries({ queryKey: key, - refetchInactive: true, + refetch: 'all', refetchPage: (page, _, allPages) => { return page === allPages[0] }, @@ -1121,7 +1081,7 @@ describe('queryClient', () => { await queryClient.resetQueries({ queryKey: key, - inactive: true, + type: 'inactive', refetchPage: (page, _, allPages) => { return page === allPages[0] }, diff --git a/src/core/tests/utils.test.tsx b/src/core/tests/utils.test.tsx index e237215270..2c907c6e95 100644 --- a/src/core/tests/utils.test.tsx +++ b/src/core/tests/utils.test.tsx @@ -2,7 +2,6 @@ import { replaceEqualDeep, partialDeepEqual, isPlainObject, - mapQueryStatusFilter, parseMutationArgs, matchMutation, scheduleMicrotask, @@ -340,26 +339,6 @@ describe('core/utils', () => { }) }) - describe('mapQueryStatusFilter', () => { - it.each` - active | inactive | statusFilter - ${true} | ${true} | ${'all'} - ${undefined} | ${undefined} | ${'all'} - ${false} | ${false} | ${'none'} - ${true} | ${false} | ${'active'} - ${true} | ${undefined} | ${'active'} - ${undefined} | ${false} | ${'active'} - ${false} | ${true} | ${'inactive'} - ${undefined} | ${true} | ${'inactive'} - ${false} | ${undefined} | ${'inactive'} - `( - 'returns "$statusFilter" when active is $active, and inactive is $inactive', - ({ active, inactive, statusFilter }) => { - expect(mapQueryStatusFilter(active, inactive)).toBe(statusFilter) - } - ) - }) - describe('parseMutationArgs', () => { it('should return mutation options', () => { const options = { mutationKey: 'key' } diff --git a/src/core/types.ts b/src/core/types.ts index 2aa3dda467..2ae8e36274 100644 --- a/src/core/types.ts +++ b/src/core/types.ts @@ -1,7 +1,7 @@ import type { MutationState } from './mutation' import type { QueryBehavior, Query } from './query' import type { RetryValue, RetryDelayValue } from './retryer' -import type { QueryFilters } from './utils' +import type { QueryFilters, QueryActivenessFilter } from './utils' export type QueryKey = string | readonly unknown[] export type EnsuredQueryKey = T extends string @@ -270,8 +270,7 @@ export interface RefetchOptions extends ResultOptions { export interface InvalidateQueryFilters extends QueryFilters, RefetchPageFilters { - refetchActive?: boolean - refetchInactive?: boolean + refetch?: QueryActivenessFilter | 'none' } export interface RefetchQueryFilters diff --git a/src/core/utils.ts b/src/core/utils.ts index 1b01474502..81989d4726 100644 --- a/src/core/utils.ts +++ b/src/core/utils.ts @@ -14,17 +14,13 @@ import type { export interface QueryFilters { /** - * Include or exclude active queries + * Filter to active queries, inactive queries or all queries */ - active?: boolean + type?: QueryActivenessFilter /** * Match query key exactly */ exact?: boolean - /** - * Include or exclude inactive queries - */ - inactive?: boolean /** * Include queries matching this predicate function */ @@ -68,7 +64,7 @@ export type Updater = | TOutput | DataUpdateFunction -export type QueryStatusFilter = 'all' | 'active' | 'inactive' | 'none' +export type QueryActivenessFilter = 'all' | 'active' | 'inactive' // UTILS @@ -173,38 +169,11 @@ export function parseMutationFilterArgs( return isQueryKey(arg1) ? { ...arg2, mutationKey: arg1 } : arg1 } -export function mapQueryStatusFilter( - active?: boolean, - inactive?: boolean -): QueryStatusFilter { - if ( - (active === true && inactive === true) || - (active == null && inactive == null) - ) { - return 'all' - } else if (active === false && inactive === false) { - return 'none' - } else { - // At this point, active|inactive can only be true|false or false|true - // so, when only one value is provided, the missing one has to be the negated value - const isActive = active ?? !inactive - return isActive ? 'active' : 'inactive' - } -} - export function matchQuery( filters: QueryFilters, query: Query ): boolean { - const { - active, - exact, - fetching, - inactive, - predicate, - queryKey, - stale, - } = filters + const { type = 'all', exact, fetching, predicate, queryKey, stale } = filters if (isQueryKey(queryKey)) { if (exact) { @@ -216,16 +185,12 @@ export function matchQuery( } } - const queryStatusFilter = mapQueryStatusFilter(active, inactive) - - if (queryStatusFilter === 'none') { - return false - } else if (queryStatusFilter !== 'all') { + if (type !== 'all') { const isActive = query.isActive() - if (queryStatusFilter === 'active' && !isActive) { + if (type === 'active' && !isActive) { return false } - if (queryStatusFilter === 'inactive' && isActive) { + if (type === 'inactive' && isActive) { return false } } From d9249fa50c95f474f2f0e65d9b239370d5959ffe Mon Sep 17 00:00:00 2001 From: Dominik Dorfmeister Date: Sat, 13 Nov 2021 22:55:52 +0100 Subject: [PATCH 2/5] feat: better query filters add a test for refetch:all I misunderstood the previous test - only key1 was matched but the created observer was inactive; the new test matches both query keys, one being active (key1) and the other having no observer at all (key2) --- src/core/tests/queryClient.test.tsx | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/core/tests/queryClient.test.tsx b/src/core/tests/queryClient.test.tsx index 2c1593f10e..5ea42b9e61 100644 --- a/src/core/tests/queryClient.test.tsx +++ b/src/core/tests/queryClient.test.tsx @@ -878,7 +878,7 @@ describe('queryClient', () => { expect(queryFn2).toHaveBeenCalledTimes(1) }) - test('should refetch inactive queries and active queries when "refetch" is "all"', async () => { + test('should refetch inactive queries when "refetch" is "inactive"', async () => { const key1 = queryKey() const key2 = queryKey() const queryFn1 = jest.fn() @@ -893,13 +893,34 @@ describe('queryClient', () => { }) const unsubscribe = observer.subscribe() queryClient.invalidateQueries(key1, { - refetch: 'all', + refetch: 'inactive', }) unsubscribe() expect(queryFn1).toHaveBeenCalledTimes(2) expect(queryFn2).toHaveBeenCalledTimes(1) }) + test('should refetch active and inactive queries when "refetch" is "all"', async () => { + const key1 = queryKey() + const key2 = queryKey() + const queryFn1 = jest.fn() + const queryFn2 = jest.fn() + await queryClient.fetchQuery(key1, queryFn1) + await queryClient.fetchQuery(key2, queryFn2) + const observer = new QueryObserver(queryClient, { + queryKey: key1, + queryFn: queryFn1, + staleTime: Infinity, + }) + const unsubscribe = observer.subscribe() + queryClient.invalidateQueries({ + refetch: 'all', + }) + unsubscribe() + expect(queryFn1).toHaveBeenCalledTimes(2) + expect(queryFn2).toHaveBeenCalledTimes(2) + }) + test('should cancel ongoing fetches if cancelRefetch option is passed', async () => { const key = queryKey() const cancelFn = jest.fn() From 9a2a5cb12078768b4e87c7ab48d35ffeee4a4e2a Mon Sep 17 00:00:00 2001 From: Dominik Dorfmeister Date: Sat, 13 Nov 2021 23:02:00 +0100 Subject: [PATCH 3/5] feat: better query filters rename refetch to refetchType to be in accordance with just type --- src/core/queryClient.ts | 4 ++-- src/core/tests/queryClient.test.tsx | 8 ++++---- src/core/types.ts | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/core/queryClient.ts b/src/core/queryClient.ts index fe933604b6..837c65fcfa 100644 --- a/src/core/queryClient.ts +++ b/src/core/queryClient.ts @@ -260,12 +260,12 @@ export class QueryClient { query.invalidate() }) - if (filters?.refetch === 'none') { + if (filters?.refetchType === 'none') { return Promise.resolve() } const refetchFilters: RefetchQueryFilters = { ...filters, - type: filters?.refetch ?? filters?.type ?? 'active', + type: filters?.refetchType ?? filters?.type ?? 'active', } return this.refetchQueries(refetchFilters, options) }) diff --git a/src/core/tests/queryClient.test.tsx b/src/core/tests/queryClient.test.tsx index 5ea42b9e61..591c4bbbfc 100644 --- a/src/core/tests/queryClient.test.tsx +++ b/src/core/tests/queryClient.test.tsx @@ -871,7 +871,7 @@ describe('queryClient', () => { }) const unsubscribe = observer.subscribe() queryClient.invalidateQueries(key1, { - refetch: 'none', + refetchType: 'none', }) unsubscribe() expect(queryFn1).toHaveBeenCalledTimes(1) @@ -893,7 +893,7 @@ describe('queryClient', () => { }) const unsubscribe = observer.subscribe() queryClient.invalidateQueries(key1, { - refetch: 'inactive', + refetchType: 'inactive', }) unsubscribe() expect(queryFn1).toHaveBeenCalledTimes(2) @@ -914,7 +914,7 @@ describe('queryClient', () => { }) const unsubscribe = observer.subscribe() queryClient.invalidateQueries({ - refetch: 'all', + refetchType: 'all', }) unsubscribe() expect(queryFn1).toHaveBeenCalledTimes(2) @@ -1070,7 +1070,7 @@ describe('queryClient', () => { await queryClient.invalidateQueries({ queryKey: key, - refetch: 'all', + refetchType: 'all', refetchPage: (page, _, allPages) => { return page === allPages[0] }, diff --git a/src/core/types.ts b/src/core/types.ts index 2ae8e36274..34236480e1 100644 --- a/src/core/types.ts +++ b/src/core/types.ts @@ -270,7 +270,7 @@ export interface RefetchOptions extends ResultOptions { export interface InvalidateQueryFilters extends QueryFilters, RefetchPageFilters { - refetch?: QueryActivenessFilter | 'none' + refetchType?: QueryActivenessFilter | 'none' } export interface RefetchQueryFilters From c108a59f2345a47cb0741e0b54219afed445ba78 Mon Sep 17 00:00:00 2001 From: Dominik Dorfmeister Date: Sun, 14 Nov 2021 09:02:46 +0100 Subject: [PATCH 4/5] feat: better query filters docs for new query filters --- docs/src/pages/guides/filters.md | 16 +++---- .../guides/migrating-to-react-query-4.md | 48 +++++++++++++++++++ docs/src/pages/reference/QueryClient.md | 23 +++++---- 3 files changed, 66 insertions(+), 21 deletions(-) diff --git a/docs/src/pages/guides/filters.md b/docs/src/pages/guides/filters.md index 9419e44d11..67d19f8fc2 100644 --- a/docs/src/pages/guides/filters.md +++ b/docs/src/pages/guides/filters.md @@ -14,25 +14,23 @@ A query filter is an object with certain conditions to match a query with: await queryClient.cancelQueries() // Remove all inactive queries that begin with `posts` in the key -queryClient.removeQueries('posts', { inactive: true }) +queryClient.removeQueries('posts', { type: 'inactive' }) // Refetch all active queries -await queryClient.refetchQueries({ active: true }) +await queryClient.refetchQueries({ type: 'active' }) // Refetch all active queries that begin with `posts` in the key -await queryClient.refetchQueries('posts', { active: true }) +await queryClient.refetchQueries('posts', { type: 'active' }) ``` A query filter object supports the following properties: - `exact?: boolean` - If you don't want to search queries inclusively by query key, you can pass the `exact: true` option to return only the query with the exact query key you have passed. -- `active?: boolean` - - When set to `true` it will match active queries. - - When set to `false` it will match inactive queries. -- `inactive?: boolean` - - When set to `true` it will match inactive queries. - - When set to `false` it will match active queries. +- `type?: 'active' | 'inactive' | 'all'` + - Defaults to `all` + - When set to `active` it will match active queries. + - When set to `inactive` it will match inactive queries. - `stale?: boolean` - When set to `true` it will match stale queries. - When set to `false` it will match fresh queries. diff --git a/docs/src/pages/guides/migrating-to-react-query-4.md b/docs/src/pages/guides/migrating-to-react-query-4.md index a62afb5b6b..c3ec75d6cb 100644 --- a/docs/src/pages/guides/migrating-to-react-query-4.md +++ b/docs/src/pages/guides/migrating-to-react-query-4.md @@ -45,3 +45,51 @@ queryClient.refetchQueries({ queryKey: ['todos'] }, { cancelRefetch: false }) ``` > Note: There is no change in behaviour for automatically triggered fetches, e.g. because a query mounts or because of a window focus refetch. + +### Query Filters + +A [query filter](../guides/filters) is an object with certain conditions to match a query. Historically, the filter options have mostly been a combination of boolean flags. However, combining those flags can lead to impossible states. Specifically: + +``` +active?: boolean + - When set to true it will match active queries. + - When set to false it will match inactive queries. +inactive?: boolean + - When set to true it will match inactive queries. + - When set to false it will match active queries. +``` + +Those flags don't work well when used together, because they are mutually exclusive. Setting `false` for both flags could match all queries, judging from the description, or no queries, which doesn't make much sense. + +With v4, those filters have been combined into a single filter to better show the intent: + +```diff +- active?: boolean +- inactive?: boolean ++ type?: 'active' | 'inactive' | 'all' +``` + +The filter defaults to `all`, and you can choose to only match `active` or `inactive` queries. + +#### refetchActive / refetchInactive + +[queryClient.invalidateQueries](../reference/QueryClient#queryclientinvalidatequeries) had two additional, similar flags: + +``` +refetchActive: Boolean + - Defaults to true + - When set to false, queries that match the refetch predicate and are actively being rendered via useQuery and friends will NOT be refetched in the background, and only marked as invalid. +refetchInactive: Boolean + - Defaults to false + - When set to true, queries that match the refetch predicate and are not being rendered via useQuery and friends will be both marked as invalid and also refetched in the background +``` + +For the same reason, those have also been combined: + +```diff +- active?: boolean +- inactive?: boolean ++ refetchType?: 'active' | 'inactive' | 'all' | 'none' +``` + +This flag defaults to `active` because `refetchActive` defaulted to `true`. This means we also need a way to tell `invalidateQueries` to not refetch at all, which is why a fourth option (`none`) is also allowed here. diff --git a/docs/src/pages/reference/QueryClient.md b/docs/src/pages/reference/QueryClient.md index c826b81f21..42f29eadaf 100644 --- a/docs/src/pages/reference/QueryClient.md +++ b/docs/src/pages/reference/QueryClient.md @@ -268,14 +268,13 @@ queryClient.setQueriesData(queryKey | filters, updater) The `invalidateQueries` method can be used to invalidate and refetch single or multiple queries in the cache based on their query keys or any other functionally accessible property/state of the query. By default, all matching queries are immediately marked as invalid and active queries are refetched in the background. -- If you **do not want active queries to refetch**, and simply be marked as invalid, you can use the `refetchActive: false` option. -- If you **want inactive queries to refetch** as well, use the `refetchInactive: true` option +- If you **do not want active queries to refetch**, and simply be marked as invalid, you can use the `refetchType: 'none'` option. +- If you **want inactive queries to refetch** as well, use the `refetchTye: 'all'` option ```js await queryClient.invalidateQueries('posts', { exact, - refetchActive: true, - refetchInactive: false + refetchType: 'active', }, { throwOnError, cancelRefetch }) ``` @@ -283,12 +282,12 @@ await queryClient.invalidateQueries('posts', { - `queryKey?: QueryKey`: [Query Keys](../guides/query-keys) - `filters?: QueryFilters`: [Query Filters](../guides/filters#query-filters) - - `refetchActive: Boolean` - - Defaults to `true` - - When set to `false`, queries that match the refetch predicate and are actively being rendered via `useQuery` and friends will NOT be refetched in the background, and only marked as invalid. - - `refetchInactive: Boolean` - - Defaults to `false` - - When set to `true`, queries that match the refetch predicate and are not being rendered via `useQuery` and friends will be both marked as invalid and also refetched in the background + - `refetchType?: 'active' | 'inactive' | 'all' | 'none'` + - Defaults to `'active'` + - When set to `active`, only queries that match the refetch predicate and are actively being rendered via `useQuery` and friends will be refetched in the background. + - When set to `inactive`, only queries that match the refetch predicate and are NOT actively being rendered via `useQuery` and friends will be refetched in the background. + - When set to `all`, all queries that match the refetch predicate will be refetched in the background. + - When set to `none`, no queries will be refetched, and those that match the refetch predicate will be marked as invalid only. - `refetchPage: (page: TData, index: number, allPages: TData[]) => boolean` - Only for [Infinite Queries](../guides/infinite-queries#refetchpage) - Use this function to specify which pages should be refetched @@ -314,10 +313,10 @@ await queryClient.refetchQueries() await queryClient.refetchQueries({ stale: true }) // refetch all active queries partially matching a query key: -await queryClient.refetchQueries(['posts'], { active: true }) +await queryClient.refetchQueries(['posts'], { type: 'active' }) // refetch all active queries exactly matching a query key: -await queryClient.refetchQueries(['posts', 1], { active: true, exact: true }) +await queryClient.refetchQueries(['posts', 1], { type: 'active', exact: true }) ``` **Options** From f7f1ee56b84c24222759b687991d886275e030be Mon Sep 17 00:00:00 2001 From: Dominik Dorfmeister Date: Sun, 14 Nov 2021 09:04:34 +0100 Subject: [PATCH 5/5] feat: better query filters rename activeness to QueryTypeFilter --- src/core/types.ts | 4 ++-- src/core/utils.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/types.ts b/src/core/types.ts index 34236480e1..7d186fa1e4 100644 --- a/src/core/types.ts +++ b/src/core/types.ts @@ -1,7 +1,7 @@ import type { MutationState } from './mutation' import type { QueryBehavior, Query } from './query' import type { RetryValue, RetryDelayValue } from './retryer' -import type { QueryFilters, QueryActivenessFilter } from './utils' +import type { QueryFilters, QueryTypeFilter } from './utils' export type QueryKey = string | readonly unknown[] export type EnsuredQueryKey = T extends string @@ -270,7 +270,7 @@ export interface RefetchOptions extends ResultOptions { export interface InvalidateQueryFilters extends QueryFilters, RefetchPageFilters { - refetchType?: QueryActivenessFilter | 'none' + refetchType?: QueryTypeFilter | 'none' } export interface RefetchQueryFilters diff --git a/src/core/utils.ts b/src/core/utils.ts index 81989d4726..65fbb7e949 100644 --- a/src/core/utils.ts +++ b/src/core/utils.ts @@ -16,7 +16,7 @@ export interface QueryFilters { /** * Filter to active queries, inactive queries or all queries */ - type?: QueryActivenessFilter + type?: QueryTypeFilter /** * Match query key exactly */ @@ -64,7 +64,7 @@ export type Updater = | TOutput | DataUpdateFunction -export type QueryActivenessFilter = 'all' | 'active' | 'inactive' +export type QueryTypeFilter = 'all' | 'active' | 'inactive' // UTILS