Skip to content

Commit c6e3f8e

Browse files
TuckerWhitehousetannerlinsley
authored andcommitted
feat(queryCache): pass query to subscribers (#765)
Any cache update triggered by a query will pass the query as the second argument to subscribers. This enables executing side-effects for specific query updates.
1 parent 3e1880f commit c6e3f8e

File tree

5 files changed

+20
-8
lines changed

5 files changed

+20
-8
lines changed

docs/src/pages/docs/api.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -580,15 +580,16 @@ The `subscribe` method can be used to subscribe to the query cache as a whole an
580580
```js
581581
import { queryCache } from 'react-query'
582582

583-
const callback = cache => {}
583+
const callback = (cache, query) => {}
584584

585585
const unsubscribe = queryCache.subscribe(callback)
586586
```
587587
588588
**Options**
589589
590-
- `callback: Function(queryCache) => void`
590+
- `callback: Function(queryCache, query?) => void`
591591
- This function will be called with the query cache any time it is updated via its tracked update mechanisms (eg, `query.setState`, `queryCache.removeQueries`, etc). Out of scope mutations to the queryCache are not encouraged and will not fire subscription callbacks
592+
- Additionally, for updates to the cache triggered by a specific query, the `query` will be passed as the second argument to the callback
592593
593594
**Returns**
594595

src/core/query.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export function makeQuery({
6565
query.dispatch = action => {
6666
query.state = queryReducer(query.state, action)
6767
query.instances.forEach(d => d.onStateUpdate(query.state))
68-
notifyGlobalListeners()
68+
notifyGlobalListeners(query)
6969
}
7070

7171
query.scheduleStaleTimeout = () => {
@@ -158,7 +158,7 @@ export function makeQuery({
158158
query.cancel()
159159
query.dispatch = noop
160160
delete queryCache.queries[query.queryHash]
161-
notifyGlobalListeners()
161+
notifyGlobalListeners(query)
162162
}
163163

164164
query.subscribe = (onStateUpdate = noop) => {

src/core/queryCache.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,21 @@ export function makeQueryCache({ frozen = isServer, defaultConfig } = {}) {
1717
const globalListeners = []
1818

1919
const configRef = defaultConfig
20-
? { current: { ...defaultConfigRef.current, ...defaultConfig }}
20+
? { current: { ...defaultConfigRef.current, ...defaultConfig } }
2121
: defaultConfigRef
2222

2323
const queryCache = {
2424
queries: {},
2525
isFetching: 0,
2626
}
2727

28-
const notifyGlobalListeners = () => {
28+
const notifyGlobalListeners = query => {
2929
queryCache.isFetching = Object.values(queryCache.queries).reduce(
3030
(acc, query) => (query.state.isFetching ? acc + 1 : acc),
3131
0
3232
)
3333

34-
globalListeners.forEach(d => d(queryCache))
34+
globalListeners.forEach(d => d(queryCache, query))
3535
}
3636

3737
queryCache.subscribe = cb => {

src/core/tests/queryCache.test.js

+11
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,17 @@ describe('queryCache', () => {
8686
expect(callback).toHaveBeenCalled()
8787
})
8888

89+
test('should include the queryCache and query when notifying listeners', () => {
90+
const callback = jest.fn()
91+
92+
queryCache.subscribe(callback)
93+
94+
queryCache.prefetchQuery('test', () => 'data')
95+
const query = queryCache.getQuery('test')
96+
97+
expect(callback).toHaveBeenCalledWith(queryCache, query)
98+
})
99+
89100
test('should notify subscribers when new query with initialData is added', async () => {
90101
const callback = jest.fn()
91102

types/index.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -627,7 +627,7 @@ export interface QueryCache {
627627
{ exact }?: { exact?: boolean }
628628
): void
629629
isFetching: number
630-
subscribe(callback: (queryCache: QueryCache) => void): () => void
630+
subscribe(callback: (queryCache: QueryCache, query?: CachedQuery<unknown>) => void): () => void
631631
clear(options?: { notify?: boolean }): void
632632
resetErrorBoundaries: () => void
633633
}

0 commit comments

Comments
 (0)