Skip to content

Commit c81e309

Browse files
authored
feat: export QueryCache and remove global query cache from docs and examples (#1017)
1 parent 959e19e commit c81e309

File tree

31 files changed

+490
-325
lines changed

31 files changed

+490
-325
lines changed

docs/src/pages/docs/api.md

Lines changed: 40 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -344,36 +344,41 @@ const promise = mutate(variables, {
344344
- `reset: Function() => void`
345345
- A function to clean the mutation internal state (i.e., it resets the mutation to its initial state).
346346
347-
## `queryCache`
348-
349-
The `queryCache` instance is the backbone of React Query that manages all of the state, caching, lifecycle and magic of every query. It supports relatively unrestricted, but safe, access to manipulate query's as you need. Its available properties and methods are:
350-
351-
- [`useQuery`](#usequery)
352-
- [`usePaginatedQuery`](#usepaginatedquery)
353-
- [`useInfiniteQuery`](#useinfinitequery)
354-
- [`useMutation`](#usemutation)
355-
- [`queryCache`](#querycache)
356-
- [`queryCache.prefetchQuery`](#querycacheprefetchquery)
357-
- [`queryCache.getQueryData`](#querycachegetquerydata)
358-
- [`queryCache.setQueryData`](#querycachesetquerydata)
359-
- [`queryCache.invalidateQueries`](#querycacheinvalidatequeries)
360-
- [`queryCache.cancelQueries`](#querycachecancelqueries)
361-
- [`queryCache.removeQueries`](#querycacheremovequeries)
362-
- [`queryCache.getQuery`](#querycachegetquery)
363-
- [`queryCache.getQueries`](#querycachegetqueries)
364-
- [`queryCache.isFetching`](#querycacheisfetching)
365-
- [`queryCache.subscribe`](#querycachesubscribe)
366-
- [`queryCache.clear`](#querycacheclear)
367-
- [`makeQueryCache`](#makequerycache)
368-
- [`useQueryCache`](#usequerycache)
369-
- [`useIsFetching`](#useisfetching)
370-
- [`ReactQueryConfigProvider`](#reactqueryconfigprovider)
371-
- [`ReactQueryCacheProvider`](#reactquerycacheprovider)
372-
- [`setConsole`](#setconsole)
373-
- [`hydration/dehydrate`](#hydrationdehydrate)
374-
- [`hydration/hydrate`](#hydrationhydrate)
375-
- [`hydration/useHydrate`](#hydrationusehydrate)
376-
- [`hydration/ReactQueryCacheProvider`](#hydrationreactquerycacheprovider)
347+
## `QueryCache`
348+
349+
The `QueryCache` is the backbone of React Query that manages all of the state, caching, lifecycle and magic of every query. It supports relatively unrestricted, but safe, access to manipulate query's as you need.
350+
351+
```js
352+
import { QueryCache } from 'react-query'
353+
354+
const queryCache = new QueryCache({
355+
defaultConfig: {
356+
queries: {
357+
staleTime: Infinity,
358+
},
359+
},
360+
})
361+
```
362+
363+
Its available properties and methods are:
364+
365+
- [`prefetchQuery`](#querycacheprefetchquery)
366+
- [`getQueryData`](#querycachegetquerydata)
367+
- [`setQueryData`](#querycachesetquerydata)
368+
- [`invalidateQueries`](#querycacheinvalidatequeries)
369+
- [`cancelQueries`](#querycachecancelqueries)
370+
- [`removeQueries`](#querycacheremovequeries)
371+
- [`getQuery`](#querycachegetquery)
372+
- [`getQueries`](#querycachegetqueries)
373+
- [`isFetching`](#querycacheisfetching)
374+
- [`subscribe`](#querycachesubscribe)
375+
- [`clear`](#querycacheclear)
376+
377+
**Options**
378+
379+
- `defaultConfig: QueryQueryConfig`
380+
- Optional
381+
- Define defaults for all queries and mutations using this query cache.
377382
378383
## `queryCache.prefetchQuery`
379384
@@ -426,8 +431,6 @@ The options for `prefetchQuery` are exactly the same as those of [`useQuery`](#u
426431
`getQueryData` is a synchronous function that can be used to get an existing query's cached data. If the query does not exist, `undefined` will be returned.
427432
428433
```js
429-
import { queryCache } from 'react-query'
430-
431434
const data = queryCache.getQueryData(queryKey)
432435
```
433436
@@ -448,8 +451,6 @@ const data = queryCache.getQueryData(queryKey)
448451
> The difference between using `setQueryData` and `prefetchQuery` is that `setQueryData` is sync and assumes that you already synchronously have the data available. If you need to fetch the data asynchronously, it's suggested that you either refetch the query key or use `prefetchQuery` to handle the asynchronous fetch.
449452
450453
```js
451-
import { queryCache } from 'react-query'
452-
453454
queryCache.setQueryData(queryKey, updater, config)
454455
```
455456
@@ -485,8 +486,6 @@ The `invalidateQueries` method can be used to invalidate and refetch single or m
485486
- If you **want inactive queries to refetch** as well, use the `refetchInactive: true` option
486487
487488
```js
488-
import { queryCache } from 'react-query'
489-
490489
const queries = queryCache.invalidateQueries(inclusiveQueryKeyOrPredicateFn, {
491490
exact,
492491
throwOnError,
@@ -525,8 +524,6 @@ The `cancelQueries` method can be used to cancel outgoing queries based on their
525524
This is most useful when performing optimistic updates since you will likely need to cancel any outgoing query refetches so they don't clobber your optimistic update when they resolve.
526525

527526
```js
528-
import { queryCache } from 'react-query'
529-
530527
const queries = queryCache.cancelQueries(queryKeyOrPredicateFn, {
531528
exact,
532529
})
@@ -552,8 +549,6 @@ This function does not return anything
552549
The `removeQueries` method can be used to remove queries from the cache based on their query keys or any other functionally accessible property/state of the query.
553550

554551
```js
555-
import { queryCache } from 'react-query'
556-
557552
const queries = queryCache.removeQueries(queryKeyOrPredicateFn, {
558553
exact,
559554
})
@@ -581,8 +576,6 @@ This function does not return anything
581576
> Note: This is not typically needed for most applications, but can come in handy when needing more information about a query in rare scenarios (eg. Looking at the query.state.updatedAt timestamp to decide whether a query is fresh enough to be used as an initial value)
582577
583578
```js
584-
import { queryCache } from 'react-query'
585-
586579
const query = queryCache.getQuery(queryKey)
587580
```
588581

@@ -603,8 +596,6 @@ const query = queryCache.getQuery(queryKey)
603596
> Note: This is not typically needed for most applications, but can come in handy when needing more information about a query in rare scenarios
604597
605598
```js
606-
import { queryCache } from 'react-query'
607-
608599
const queries = queryCache.getQueries(queryKey)
609600
```
610601

@@ -623,8 +614,6 @@ const queries = queryCache.getQueries(queryKey)
623614
This `isFetching` property is 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)
624615

625616
```js
626-
import { queryCache } from 'react-query'
627-
628617
if (queryCache.isFetching) {
629618
console.log('At least one query is fetching!')
630619
}
@@ -637,8 +626,6 @@ React Query also exports a handy [`useIsFetching`](#useisfetching) hook that wil
637626
The `subscribe` method can be used to subscribe to the query cache as a whole and be informed of safe/known updates to the cache like query states changing or queries being updated, added or removed
638627

639628
```js
640-
import { queryCache } from 'react-query'
641-
642629
const callback = (cache, query) => {}
643630

644631
const unsubscribe = queryCache.subscribe(callback)
@@ -660,8 +647,6 @@ const unsubscribe = queryCache.subscribe(callback)
660647
The `clear` method can be used to clear the queryCache entirely and start fresh.
661648

662649
```js
663-
import { queryCache } from 'react-query'
664-
665650
queryCache.clear()
666651
```
667652

@@ -672,20 +657,7 @@ queryCache.clear()
672657

673658
## `makeQueryCache`
674659

675-
`makeQueryCache` creates an empty `queryCache` manually. This is useful together with `ReactQueryCacheProvider` to have multiple caches in your application.
676-
677-
As opposed to the global cache, caches created by `makeQueryCache` caches data even on the server.
678-
679-
```js
680-
import { makeQueryCache } from 'react-query'
681-
682-
const queryCache = makeQueryCache()
683-
```
684-
685-
**Returns**
686-
687-
- `queryCache: QueryCache`
688-
- An empty `queryCache`
660+
The `makeQueryCache` factory function has been deprecated in favor of `new QueryCache()`.
689661

690662
## `useQueryCache`
691663

@@ -697,8 +669,6 @@ import { useQueryCache } from 'react-query'
697669
const queryCache = useQueryCache()
698670
```
699671

700-
If you are using the `ReactQueryCacheProvider` to set a custom cache, you cannot simply import `{ queryCache }` any more. This hook will ensure you're getting the correct instance.
701-
702672
## `useIsFetching`
703673

704674
`useIsFetching` is an optional hook that returns the `number` of the queries that your application is loading or fetching in the background (useful for app-wide loading indicators).
@@ -772,12 +742,12 @@ function App() {
772742

773743
## `ReactQueryCacheProvider`
774744

775-
`ReactQueryCacheProvider` is an optional provider component for explicitly setting the query cache used by React Query. This is useful for creating component-level caches that are not completely global, as well as making truly isolated unit tests.
745+
The query cache can be connected to React with the `ReactQueryCacheProvider`. This component puts the cache on the context, which enables you to access it from anywhere in your component tree.
776746

777747
```js
778-
import { ReactQueryCacheProvider, makeQueryCache } from 'react-query'
748+
import { ReactQueryCacheProvider, QueryCache } from 'react-query'
779749

780-
const queryCache = makeQueryCache()
750+
const queryCache = new QueryCache()
781751

782752
function App() {
783753
return (
@@ -791,8 +761,7 @@ function App() {
791761
**Options**
792762

793763
- `queryCache: QueryCache`
794-
- In instance of queryCache, you can use the `makeQueryCache` factory to create this.
795-
- If not provided, a new cache will be generated.
764+
- Instance of QueryCache.
796765

797766
## `ReactQueryErrorResetBoundary`
798767

docs/src/pages/docs/guides/invalidations-from-mutations.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ const [mutate] = useMutation(postTodo)
1414
When a successful `postTodo` mutation happens, we likely want all `todos` queries to get invalidated and possibly refetched to show the new todo item. To do this, you can use `useMutation`'s `onSuccess` options and the `queryCache`'s `invalidateQueries` function:
1515

1616
```js
17-
import { useMutation, queryCache } from 'react-query'
17+
import { useMutation, useQueryCache } from 'react-query'
18+
19+
const queryCache = useQueryCache()
1820

1921
// When this mutation succeeds, invalidate any queries with the `todos` or `reminders` query key
2022
const [mutate] = useMutation(addTodo, {

docs/src/pages/docs/guides/prefetching.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ title: Prefetching
66
If you're lucky enough, you may know enough about what your users will do to be able to prefetch the data they need before it's needed! If this is the case, you can use the `prefetchQuery` function to prefetch the results of a query to be placed into the cache:
77

88
```js
9-
import { queryCache } from 'react-query'
10-
119
const prefetchTodos = async () => {
1210
const queryData = await queryCache.prefetchQuery('todos', () =>
1311
fetch('/todos')
@@ -25,7 +23,5 @@ If a prefetched query is rendered after the `staleTime` for a prefetched query,
2523
Alternatively, if you already have the data for your query synchronously available, you don't need to prefetch it. You can just use the [Query Cache's `setQueryData` method](../api/#querycachesetquerydata) to directly add or update a query's cached result.
2624

2725
```js
28-
import { queryCache } from 'react-query'
29-
3026
queryCache.setQueryData('todos', todos)
3127
```

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ title: Query Invalidation
66
Waiting for queries to become stale before they are fetched again doesn't always work, especially when you know for a fact that a query needs to get refetched. For that purpose, the `queryCache` has an `invalidateQueries` method that lets you manually mark queries as stale and potentially refetch them too!
77

88
```js
9-
import { queryCache } from 'react-query'
10-
119
queryCache.invalidateQueries('todos')
1210
```
1311

@@ -25,7 +23,10 @@ When using APIs like `invalidateQueries` and `removeQueries` (and others that su
2523
In this example, we can use the `todos` prefix to invalidate any queries that start with `todos` in their query key:
2624

2725
```js
28-
import { queryCache, useQuery } from 'react-query'
26+
import { useQuery, useQueryCache } from 'react-query'
27+
28+
// Get QueryCache from the context
29+
const queryCache = useQueryCache()
2930

3031
queryCache.invalidateQueries('todos')
3132

docs/src/pages/docs/guides/ssr.md

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,14 @@ To support caching queries on the server and set up hydration, you start with wr
5959

6060
```jsx
6161
// _app.jsx
62-
import { ReactQueryCacheProvider } from 'react-query'
62+
import { ReactQueryCacheProvider, QueryCache } from 'react-query'
6363
import { Hydrate } from 'react-query/hydration'
6464

65+
const queryCache = new QueryCache()
66+
6567
export default function MyApp({ Component, pageProps }) {
6668
return (
67-
<ReactQueryCacheProvider>
69+
<ReactQueryCacheProvider queryCache={queryCache}>
6870
<Hydrate state={pageProps.dehydratedState}>
6971
<Component {...pageProps} />
7072
</Hydrate>
@@ -77,11 +79,11 @@ Now you are ready to prefetch some data in your pages with either [`getStaticPro
7779

7880
```jsx
7981
// pages/posts.jsx
80-
import { makeQueryCache } from 'react-query'
82+
import { QueryCache } from 'react-query'
8183
import { dehydrate } from 'react-query/hydration'
8284

8385
export async function getStaticProps() {
84-
const queryCache = makeQueryCache()
86+
const queryCache = new QueryCache()
8587

8688
await queryCache.prefetchQuery('posts', getPosts)
8789

@@ -116,37 +118,38 @@ Since there are many different possible setups for SSR, it's hard to give a deta
116118
> Note: The global `queryCache` you can import directly from 'react-query' does not cache queries on the server to avoid leaking sensitive information between requests.
117119
118120
- Prefetch data
119-
- Create a `prefetchQueryCache` specifically for prefetching by calling `const prefetchQueryCache = makeQueryCache()`
121+
- Create a `prefetchQueryCache` specifically for prefetching by calling `const prefetchQueryCache = new QueryCache()`
120122
- Call `prefetchQueryCache.prefetchQuery(...)` to prefetch queries
121123
- Dehydrate by using `const dehydratedState = dehydrate(prefetchQueryCache)`
122124
- Render
123-
- Wrap the app in `<ReactQueryCacheProvider>` and `<Hydrate>` to create a new cache and hydrate the state
124-
- This makes sure a separate `queryCache` is created specifically for rendering
125-
- **Do not** pass in the `prefetchQueryCache` from the last step, the server and client both needs to render from the dehydrated data to avoid React hydration mismatches. This is because queries with errors are excluded from dehydration by default.
125+
- Create a new render query cache and hydrate the state. Use this query cache to render your app.
126+
- **Do not** use the `prefetchQueryCache` to render your app, the server and client both needs to render from the dehydrated data to avoid React hydration mismatches. This is because queries with errors are excluded from dehydration by default.
126127
- Serialize and embed `dehydratedState` in the markup
127128
- Security note: Serializing data with `JSON.stringify` can put you at risk for XSS-vulnerabilities, [this blog post explains why and how to solve it](https://medium.com/node-security/the-most-common-xss-vulnerability-in-react-js-applications-2bdffbcc1fa0)
128129

129130
**Client side**
130131

131132
- Parse `dehydratedState` from where you put it in the markup
133+
- Create a cache and hydrate the state
132134
- Render
133-
- Wrap the app in `<Hydrate>` from `'react-query/hydration'` and pass in the dehyrated state.
134135

135136
This list aims to be exhaustive, but depending on your current setup, the above steps can take more or less work. Here is a barebones example:
136137

137138
```jsx
138139
// Server
139-
const prefetchCache = makeQueryCache()
140+
const prefetchCache = new QueryCache()
140141
await prefetchCache.prefetchQuery('key', fn)
141142
const dehydratedState = dehydrate(prefetchCache)
142143

144+
const renderCache = new QueryCache()
145+
hydrate(renderCache, dehydratedState)
146+
143147
const html = ReactDOM.renderToString(
144-
<ReactQueryCacheProvider>
145-
<Hydrate state={dehyratedState}>
146-
<App />
147-
</Hydrate>
148+
<ReactQueryCacheProvider queryCache={renderCache}>
149+
<App />
148150
</ReactQueryCacheProvider>
149151
)
152+
150153
res.send(`
151154
<html>
152155
<body>
@@ -160,11 +163,13 @@ res.send(`
160163

161164
// Client
162165
const dehydratedState = JSON.parse(window.__REACT_QUERY_INITIAL_QUERIES__)
166+
167+
const queryCache = new QueryCache()
168+
hydrate(queryCache, dehydratedState)
169+
163170
ReactDOM.hydrate(
164-
<ReactQueryCacheProvider>
165-
<Hydrate state={dehyratedState}>
166-
<App />
167-
</Hydrate>
171+
<ReactQueryCacheProvider queryCache={queryCache}>
172+
<App />
168173
</ReactQueryCacheProvider>
169174
)
170175
```

docs/src/pages/docs/overview.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,19 @@ In the example below, you can see React Query in its most basic and simple form
4747
[Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-query/tree/master/examples/simple)
4848

4949
```js
50-
import { useQuery } from 'react-query'
50+
import { useQuery, QueryCache, ReactQueryCacheProvider } from 'react-query'
51+
52+
const queryCache = new QueryCache()
5153

5254
export default function App() {
55+
return (
56+
<ReactQueryCacheProvider queryCache={queryCache}>
57+
<Example />
58+
</ReactQueryCacheProvider>
59+
)
60+
}
61+
62+
function Example() {
5363
const { isLoading, error, data } = useQuery('repoData', () =>
5464
fetch('https://api.github.com/repos/tannerlinsley/react-query').then(res =>
5565
res.json()

0 commit comments

Comments
 (0)