Skip to content

Commit 14c4ec6

Browse files
authored
feat: change ReactQueryCacheProvider from hydration to Hydrate (#943)
1 parent 211edc0 commit 14c4ec6

File tree

6 files changed

+99
-115
lines changed

6 files changed

+99
-115
lines changed

docs/src/pages/docs/api.md

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -792,13 +792,13 @@ setConsole({
792792
793793
## `hydration/dehydrate`
794794
795-
`dehydrate` creates a frozen representation of a `queryCache` that can later be hydrated with `useHydrate`, `hydrate` or by passing it into `hydration/ReactQueryCacheProvider`. This is useful for passing prefetched queries from server to client or persisting queries to localstorage. It only includes currently successful queries by default.
795+
`dehydrate` creates a frozen representation of a `queryCache` that can later be hydrated with `useHydrate`, `hydrate` or `Hydrate`. This is useful for passing prefetched queries from server to client or persisting queries to localstorage. It only includes currently successful queries by default.
796796
797797
```js
798798
import { dehydrate } from 'react-query/hydration'
799799

800800
const dehydratedState = dehydrate(queryCache, {
801-
shouldDehydrate
801+
shouldDehydrate,
802802
})
803803
```
804804
@@ -824,7 +824,7 @@ const dehydratedState = dehydrate(queryCache, {
824824
`hydrate` adds a previously dehydrated state into a `queryCache`. If the queries included in dehydration already exist in the cache, `hydrate` does not overwrite them.
825825
826826
```js
827-
import { hydrate } from 'react-query/hydration'
827+
import { hydrate } from 'react-query/hydration'
828828

829829
hydrate(queryCache, dehydratedState)
830830
```
@@ -854,31 +854,19 @@ useHydrate(dehydratedState)
854854
- **Required**
855855
- The state to hydrate
856856
857-
## `hydration/ReactQueryCacheProvider`
857+
## `hydration/Hydrate`
858858
859-
`hydration/ReactQueryCacheProvider` does the same thing as `ReactQueryCacheProvider` but also supports hydrating an initial state into the cache.
859+
`hydration/Hydrate` does the same thing as `useHydrate` but exposed as a component.
860860
861861
```js
862-
import { ReactQueryCacheProvider } from 'react-query/hydration'
862+
import { Hydrate } from 'react-query/hydration'
863863

864864
function App() {
865-
return (
866-
<ReactQueryCacheProvider
867-
queryCache={queryCache}
868-
dehydratedState={dehydratedState}
869-
hydrationConfig={hydrationConfig}>
870-
...
871-
</ReactQueryCacheProvider>
872-
)
865+
return <Hydrate state={dehydratedState}>...</Hydrate>
873866
}
874867
```
875868
876869
**Options**
877870
878-
- `queryCache: QueryCache`
879-
- In instance of queryCache, you can use the `makeQueryCache` factory to create this.
880-
- If not provided, a new cache will be generated.
881-
- `dehydratedState: DehydratedState`
871+
- `state: DehydratedState`
882872
- The state to hydrate
883-
- `hydrationConfig`
884-
- Same config as for `hydrate`

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

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ This approach works well for applications or user-specific pages that might cont
1313

1414
React Query supports two ways of prefetching data on the server and passing that to the client.
1515

16-
* Prefetch the data yourself and pass it in as `initialData`
17-
* Quick to set up for simple cases
18-
* Has some caveats
19-
* Prefetch the query via React Query and use de/rehydration
20-
* Requires slightly more setup up front
16+
- Prefetch the data yourself and pass it in as `initialData`
17+
- Quick to set up for simple cases
18+
- Has some caveats
19+
- Prefetch the query via React Query and use de/rehydration
20+
- Requires slightly more setup up front
2121

2222
The exact implementation of these mechanisms may vary from platform to platform, but we recommend starting with Next.js which supports [2 forms of pre-rendering](https://nextjs.org/docs/basic-features/data-fetching):
2323

@@ -45,28 +45,29 @@ function Posts(props) {
4545

4646
The setup is minimal and this can be a perfect solution for some cases, but there are a few tradeoffs compared to the full approach:
4747

48-
* If you are calling `useQuery` in a component deeper down in the tree you need to pass the `initialData` down to that point
49-
* If you are calling `useQuery` with the same query in multiple locations, you need to pass `initialData` to all of them
50-
* There is no way to know at what time the query was fetched on the server, so `updatedAt` and determining if the query needs refetching is based on when the page loaded instead
48+
- If you are calling `useQuery` in a component deeper down in the tree you need to pass the `initialData` down to that point
49+
- If you are calling `useQuery` with the same query in multiple locations, you need to pass `initialData` to all of them
50+
- There is no way to know at what time the query was fetched on the server, so `updatedAt` and determining if the query needs refetching is based on when the page loaded instead
5151

5252
## Prefetch the query via React Query and use de/rehydration
5353

5454
React Query supports prefetching a query on the server and handing off or _dehydrating_ that query to the client. This means the server can prerender markup that is immediately available on page load and as soon as JS is available, React Query can upgrade or _hydrate_ those queries with the full functionality of the library. This includes refetching those queries on the client if they have become stale since the time they were rendered on the server.
5555

5656
### Integrating with Next.js
5757

58-
To support caching queries on the server and set up hydration, you start with wrapping your application with `<ReactQueryCacheProvider>` in `_app.js`.
59-
60-
> Note: You need to import `ReactQueryCacheProvider` from `'react-query/hydration'` for it to support hydration!
58+
To support caching queries on the server and set up hydration, you start with wrapping your application with `<ReactQueryCacheProvider>` and `<Hydrate>` in `_app.js`.
6159

6260
```jsx
6361
// _app.jsx
64-
import { ReactQueryCacheProvider } from 'react-query/hydration'
62+
import { ReactQueryCacheProvider } from 'react-query'
63+
import { Hydrate } from 'react-query/hydration'
6564

6665
export default function MyApp({ Component, pageProps }) {
6766
return (
68-
<ReactQueryCacheProvider dehydratedState={pageProps.dehydratedState}>
69-
<Component {...pageProps} />
67+
<ReactQueryCacheProvider>
68+
<Hydrate state={pageProps.dehydratedState}>
69+
<Component {...pageProps} />
70+
</Hydrate>
7071
</ReactQueryCacheProvider>
7172
)
7273
}
@@ -86,8 +87,8 @@ export async function getStaticProps() {
8687

8788
return {
8889
props: {
89-
dehydratedState: dehydrate(queryCache)
90-
}
90+
dehydratedState: dehydrate(queryCache),
91+
},
9192
}
9293
}
9394

@@ -119,7 +120,7 @@ Since there are many different possible setups for SSR, it's hard to give a deta
119120
- Call `prefetchQueryCache.prefetchQuery(...)` to prefetch queries
120121
- Dehydrate by using `const dehydratedState = dehydrate(prefetchQueryCache)`
121122
- Render
122-
- Wrap the app in `<ReactQueryCacheProvider>` from `'react-query/hydration'` and pass in `dehydratedState`
123+
- Wrap the app in `<ReactQueryCacheProvider>` and `<Hydrate>` to create a new cache and hydrate the state
123124
- This makes sure a separate `queryCache` is created specifically for rendering
124125
- **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.
125126
- Serialize and embed `dehydratedState` in the markup
@@ -129,7 +130,7 @@ Since there are many different possible setups for SSR, it's hard to give a deta
129130

130131
- Parse `dehydratedState` from where you put it in the markup
131132
- Render
132-
- Wrap the app in `<ReactQueryCacheProvider>` from `'react-query/hydration'` and pass in `dehydratedState`
133+
- Wrap the app in `<Hydrate>` from `'react-query/hydration'` and pass in the dehyrated state.
133134

134135
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:
135136

@@ -140,24 +141,30 @@ await prefetchCache.prefetchQuery('key', fn)
140141
const dehydratedState = dehydrate(prefetchCache)
141142

142143
const html = ReactDOM.renderToString(
143-
<ReactQueryCacheProvider dehydratedState={dehydratedState}>
144-
<App />
144+
<ReactQueryCacheProvider>
145+
<Hydrate state={dehyratedState}>
146+
<App />
147+
</Hydrate>
145148
</ReactQueryCacheProvider>
146149
)
147150
res.send(`
148151
<html>
149152
<body>
150153
<div id="app">${html}</div>
151-
<script>window.__REACT_QUERY_INITIAL_QUERIES__ = ${JSON.stringify(dehydratedState)};</script>
154+
<script>window.__REACT_QUERY_INITIAL_QUERIES__ = ${JSON.stringify(
155+
dehydratedState
156+
)};</script>
152157
</body>
153158
</html>
154159
`)
155160

156161
// Client
157162
const dehydratedState = JSON.parse(window.__REACT_QUERY_INITIAL_QUERIES__)
158163
ReactDOM.hydrate(
159-
<ReactQueryCacheProvider dehydratedState={dehydratedState}>
160-
<App />
164+
<ReactQueryCacheProvider>
165+
<Hydrate state={dehyratedState}>
166+
<App />
167+
</Hydrate>
161168
</ReactQueryCacheProvider>
162169
)
163170
```

src/hydration/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
export { dehydrate, hydrate } from './hydration'
2-
export { useHydrate, ReactQueryCacheProvider } from './react'
2+
export { useHydrate, Hydrate } from './react'
33

44
// Types
55
export type {
@@ -9,4 +9,4 @@ export type {
99
ShouldDehydrateFunction,
1010
DehydrateConfig,
1111
} from './hydration'
12-
export type { HydrationCacheProviderProps } from './react'
12+
export type { HydrateProps } from './react'

src/hydration/react.tsx

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
import React from 'react'
2-
import {
3-
useQueryCache,
4-
ReactQueryCacheProvider as CacheProvider,
5-
} from 'react-query'
6-
import { hydrate } from './hydration'
2+
import { useQueryCache } from 'react-query'
73

8-
import type { ReactQueryCacheProviderProps } from '../react'
4+
import { hydrate } from './hydration'
95

106
export function useHydrate(queries: unknown) {
117
const queryCache = useQueryCache()
@@ -21,28 +17,11 @@ export function useHydrate(queries: unknown) {
2117
}, [queryCache, queries])
2218
}
2319

24-
interface HydratorProps {
25-
dehydratedState?: unknown
20+
export interface HydrateProps {
21+
state?: unknown
2622
}
2723

28-
const Hydrator: React.FC<HydratorProps> = ({ dehydratedState, children }) => {
29-
useHydrate(dehydratedState)
24+
export const Hydrate: React.FC<HydrateProps> = ({ state, children }) => {
25+
useHydrate(state)
3026
return children as React.ReactElement<any>
3127
}
32-
33-
export interface HydrationCacheProviderProps
34-
extends ReactQueryCacheProviderProps {
35-
dehydratedState?: unknown
36-
}
37-
38-
export const ReactQueryCacheProvider: React.FC<HydrationCacheProviderProps> = ({
39-
dehydratedState,
40-
children,
41-
...rest
42-
}) => {
43-
return (
44-
<CacheProvider {...rest}>
45-
<Hydrator dehydratedState={dehydratedState}>{children}</Hydrator>
46-
</CacheProvider>
47-
)
48-
}

src/hydration/tests/react.test.tsx

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
import React from 'react'
22
import { render } from '@testing-library/react'
33

4-
import {
5-
ReactQueryCacheProvider as OriginalCacheProvider,
6-
makeQueryCache,
7-
useQuery,
8-
} from '../..'
9-
import { dehydrate, useHydrate, ReactQueryCacheProvider } from '../'
4+
import { ReactQueryCacheProvider, makeQueryCache, useQuery } from '../..'
5+
import { dehydrate, useHydrate, Hydrate } from '../'
106
import { waitForMs } from '../../react/tests/utils'
117

128
describe('React hydration', () => {
@@ -58,9 +54,9 @@ describe('React hydration', () => {
5854
}
5955

6056
const rendered = render(
61-
<OriginalCacheProvider queryCache={clientQueryCache}>
57+
<ReactQueryCacheProvider queryCache={clientQueryCache}>
6258
<Page />
63-
</OriginalCacheProvider>
59+
</ReactQueryCacheProvider>
6460
)
6561

6662
await waitForMs(10)
@@ -84,11 +80,10 @@ describe('React hydration', () => {
8480
}
8581

8682
const rendered = render(
87-
<ReactQueryCacheProvider
88-
queryCache={clientQueryCache}
89-
dehydratedState={dehydratedState}
90-
>
91-
<Page queryKey={'string'} />
83+
<ReactQueryCacheProvider queryCache={clientQueryCache}>
84+
<Hydrate state={dehydratedState}>
85+
<Page queryKey={'string'} />
86+
</Hydrate>
9287
</ReactQueryCacheProvider>
9388
)
9489

@@ -104,12 +99,11 @@ describe('React hydration', () => {
10499
intermediateCache.clear({ notify: false })
105100

106101
rendered.rerender(
107-
<ReactQueryCacheProvider
108-
queryCache={clientQueryCache}
109-
dehydratedState={dehydrated}
110-
>
111-
<Page queryKey={'string'} />
112-
<Page queryKey={'added string'} />
102+
<ReactQueryCacheProvider queryCache={clientQueryCache}>
103+
<Hydrate state={dehydrated}>
104+
<Page queryKey={'string'} />
105+
<Page queryKey={'added string'} />
106+
</Hydrate>
113107
</ReactQueryCacheProvider>
114108
)
115109

@@ -137,11 +131,10 @@ describe('React hydration', () => {
137131
}
138132

139133
const rendered = render(
140-
<ReactQueryCacheProvider
141-
queryCache={clientQueryCache}
142-
dehydratedState={dehydratedState}
143-
>
144-
<Page />
134+
<ReactQueryCacheProvider queryCache={clientQueryCache}>
135+
<Hydrate state={dehydratedState}>
136+
<Page />
137+
</Hydrate>
145138
</ReactQueryCacheProvider>
146139
)
147140

@@ -151,11 +144,10 @@ describe('React hydration', () => {
151144
const newClientQueryCache = makeQueryCache()
152145

153146
rendered.rerender(
154-
<ReactQueryCacheProvider
155-
queryCache={newClientQueryCache}
156-
dehydratedState={dehydratedState}
157-
>
158-
<Page />
147+
<ReactQueryCacheProvider queryCache={newClientQueryCache}>
148+
<Hydrate state={dehydratedState}>
149+
<Page />
150+
</Hydrate>
159151
</ReactQueryCacheProvider>
160152
)
161153

0 commit comments

Comments
 (0)