From b265f63de991c6e61975efa772ede77bc5156e2d Mon Sep 17 00:00:00 2001 From: Tanner Linsley Date: Tue, 8 Dec 2020 13:05:55 -0700 Subject: [PATCH 1/4] feat: reset query utils --- src/core/query.ts | 9 ++++++++- src/core/queryCache.ts | 17 +++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/core/query.ts b/src/core/query.ts index 990bfc9a9a..2f96a01ca5 100644 --- a/src/core/query.ts +++ b/src/core/query.ts @@ -124,6 +124,7 @@ export class Query { queryKey: QueryKey queryHash: string options!: QueryOptions + initialState: QueryState state: QueryState cacheTime!: number @@ -141,7 +142,8 @@ export class Query { this.cache = config.cache this.queryKey = config.queryKey this.queryHash = config.queryHash - this.state = config.state || this.getDefaultState(this.options) + this.initialState = config.state || this.getDefaultState(this.options) + this.state = this.initialState this.scheduleGc() } @@ -220,6 +222,11 @@ export class Query { this.cancel() } + reset(): void { + this.destroy() + this.setState(this.initialState) + } + isActive(): boolean { return this.observers.some(observer => observer.options.enabled !== false) } diff --git a/src/core/queryCache.ts b/src/core/queryCache.ts index b0591151f0..8cd3e0270f 100644 --- a/src/core/queryCache.ts +++ b/src/core/queryCache.ts @@ -80,6 +80,15 @@ export class QueryCache extends Subscribable { } } + reset(query: Query): void { + const queryInMap = this.queriesMap[query.queryHash] + + if (queryInMap) { + query.reset() + this.notify(query) + } + } + clear(): void { notifyManager.batch(() => { this.queries.forEach(query => { @@ -88,6 +97,14 @@ export class QueryCache extends Subscribable { }) } + resetAll(): void { + notifyManager.batch(() => { + this.queries.forEach(query => { + this.reset(query) + }) + }) + } + get( queryHash: string ): Query | undefined { From 95fe412a8ebeb87a2f424f2b3937c9846c442f06 Mon Sep 17 00:00:00 2001 From: Tanner Linsley Date: Tue, 8 Dec 2020 13:20:52 -0700 Subject: [PATCH 2/4] Update queryClient.ts --- src/core/queryClient.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/core/queryClient.ts b/src/core/queryClient.ts index 8161343fb6..ddf1b6c2c0 100644 --- a/src/core/queryClient.ts +++ b/src/core/queryClient.ts @@ -132,6 +132,18 @@ export class QueryClient { }) } + resetQueries(filters?: QueryFilters): void + resetQueries(queryKey?: QueryKey, filters?: QueryFilters): void + resetQueries(arg1?: QueryKey | QueryFilters, arg2?: QueryFilters): void { + const [filters] = parseFilterArgs(arg1, arg2) + const queryCache = this.queryCache + notifyManager.batch(() => { + queryCache.findAll(filters).forEach(query => { + queryCache.reset(query) + }) + }) + } + cancelQueries(filters?: QueryFilters, options?: CancelOptions): Promise cancelQueries( queryKey?: QueryKey, From 77c817f7d13d9b50f811b23f9f881d57c0be59c6 Mon Sep 17 00:00:00 2001 From: Aaron Jensen Date: Sat, 12 Dec 2020 01:57:14 -0600 Subject: [PATCH 3/4] Reset query docs and tests (#1393) * docs: Add resetQueries * test: Add resetQueries tests --- docs/src/pages/reference/QueryClient.md | 25 +++++++++++++ src/core/tests/queryCache.test.tsx | 50 +++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/docs/src/pages/reference/QueryClient.md b/docs/src/pages/reference/QueryClient.md index 4858476ea4..4e34813aee 100644 --- a/docs/src/pages/reference/QueryClient.md +++ b/docs/src/pages/reference/QueryClient.md @@ -32,6 +32,7 @@ Its available methods are: - [`refetchQueries`](#queryclientrefetchqueries) - [`cancelQueries`](#queryclientcancelqueries) - [`removeQueries`](#queryclientremovequeries) +- [`resetQueries`](#queryclientresetqueries) - [`isFetching`](#queryclientisfetching) - [`getDefaultOptions`](#queryclientsetdefaultoptions) - [`setDefaultOptions`](#queryclientgetdefaultoptions) @@ -274,6 +275,30 @@ queryClient.removeQueries(queryKey, { exact: true }) This method does not return anything +## `queryClient.resetQueries` + +The `resetQueries` method can be used to reset queries in the cache to their +initial state based on their query keys or any other functionally accessible +property/state of the query. + +This will notify subscribers — unlike `clear`, which removes all +subscribers — and reset the query to its pre-loaded state — unlike +`invalidateQueries`. If a query has `initialData`, the query's data will be +reset to that. + +```js +queryClient.resetQueries(queryKey, { exact: true }) +``` + +**Options** + +- `queryKey?: QueryKey`: [Query Keys](../guides/query-keys) +- `filters?: QueryFilters`: [Query Filters](../guides/query-filters) + +**Returns** + +This method does not return anything + ## `queryClient.isFetching` This `isFetching` method returns an `integer` representing how many queries, if any, in the cache are currently fetching (including background-fetching, loading new pages, or loading more infinite query results) diff --git a/src/core/tests/queryCache.test.tsx b/src/core/tests/queryCache.test.tsx index 877e36c47b..1470d7d7e4 100644 --- a/src/core/tests/queryCache.test.tsx +++ b/src/core/tests/queryCache.test.tsx @@ -948,6 +948,56 @@ describe('queryCache', () => { expect(queryFn2).toHaveBeenCalledTimes(1) }) + test('should notify listeners when a query is reset', async () => { + const key = queryKey() + + const callback = jest.fn() + + await queryClient.prefetchQuery(key, () => 'data') + + queryCache.subscribe(callback) + + queryClient.resetQueries(key) + + expect(callback).toHaveBeenCalled() + }) + + test('resetQueries should reset query', async () => { + const key = queryKey() + + await queryClient.prefetchQuery(key, () => 'data') + + let state = queryClient.getQueryState(key) + expect(state?.data).toEqual('data') + expect(state?.status).toEqual('success') + + queryClient.resetQueries(key) + + state = queryClient.getQueryState(key) + + expect(state).toBeTruthy() + expect(state?.data).toBeUndefined() + expect(state?.status).toEqual('idle') + }) + + test('resetQueries should reset query data to initial data if set', async () => { + const key = queryKey() + + await queryClient.prefetchQuery(key, () => 'data', { + initialData: 'initial', + }) + + let state = queryClient.getQueryState(key) + expect(state?.data).toEqual('data') + + queryClient.resetQueries(key) + + state = queryClient.getQueryState(key) + + expect(state).toBeTruthy() + expect(state?.data).toEqual('initial') + }) + test('find should filter correctly', async () => { const key = queryKey() const testCache = new QueryCache() From 5906d12c25ef90dabf85b50f08166d92048f6b8f Mon Sep 17 00:00:00 2001 From: Tanner Linsley Date: Sat, 12 Dec 2020 01:03:14 -0700 Subject: [PATCH 4/4] remove unnecessary queryCache.reset methods --- src/core/queryCache.ts | 17 ----------------- src/core/queryClient.ts | 2 +- 2 files changed, 1 insertion(+), 18 deletions(-) diff --git a/src/core/queryCache.ts b/src/core/queryCache.ts index 8cd3e0270f..b0591151f0 100644 --- a/src/core/queryCache.ts +++ b/src/core/queryCache.ts @@ -80,15 +80,6 @@ export class QueryCache extends Subscribable { } } - reset(query: Query): void { - const queryInMap = this.queriesMap[query.queryHash] - - if (queryInMap) { - query.reset() - this.notify(query) - } - } - clear(): void { notifyManager.batch(() => { this.queries.forEach(query => { @@ -97,14 +88,6 @@ export class QueryCache extends Subscribable { }) } - resetAll(): void { - notifyManager.batch(() => { - this.queries.forEach(query => { - this.reset(query) - }) - }) - } - get( queryHash: string ): Query | undefined { diff --git a/src/core/queryClient.ts b/src/core/queryClient.ts index ddf1b6c2c0..af2a300744 100644 --- a/src/core/queryClient.ts +++ b/src/core/queryClient.ts @@ -139,7 +139,7 @@ export class QueryClient { const queryCache = this.queryCache notifyManager.batch(() => { queryCache.findAll(filters).forEach(query => { - queryCache.reset(query) + query.reset() }) }) }