Skip to content

Commit

Permalink
feat: add support for default options when hydrating
Browse files Browse the repository at this point in the history
  • Loading branch information
boschni committed Oct 7, 2020
1 parent 1de4ca9 commit dcb3e7f
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 26 deletions.
4 changes: 4 additions & 0 deletions docs/src/pages/reference/hydration/HydrateComp.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,7 @@ function App() {

- `state: DehydratedState`
- The state to hydrate
- `options: HydrateOptions`
- Optional
- `defaultOptions: QueryOptions`
- The default query options to use for the hydrated queries.
10 changes: 6 additions & 4 deletions docs/src/pages/reference/hydration/dehydrate.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ const dehydratedState = dehydrate(cache, {
- `cache: QueryCache`
- **Required**
- The `cache` that should be dehydrated
- `shouldDehydrate: (query: Query) => boolean`
- This function is called for each query in the cache
- Return `true` to include this query in dehydration, or `false` otherwise
- Default version only includes successful queries, do `shouldDehydrate: () => true` to include all queries
- `options: DehydrateOptions`
- Optional
- `shouldDehydrate: (query: Query) => boolean`
- This function is called for each query in the cache
- Return `true` to include this query in dehydration, or `false` otherwise
- Default version only includes successful queries, do `shouldDehydrate: () => true` to include all queries

**Returns**

Expand Down
6 changes: 5 additions & 1 deletion docs/src/pages/reference/hydration/hydrate.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ title: hydration/hydrate
```js
import { hydrate } from 'react-query/hydration'

hydrate(cache, dehydratedState)
hydrate(cache, dehydratedState, options)
```

**Options**
Expand All @@ -19,3 +19,7 @@ hydrate(cache, dehydratedState)
- `dehydratedState: DehydratedState`
- **Required**
- The state to hydrate into the cache
- `options: HydrateOptions`
- Optional
- `defaultOptions: QueryOptions`
- The default query options to use for the hydrated queries.
6 changes: 5 additions & 1 deletion docs/src/pages/reference/hydration/useHydrate.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,15 @@ title: hydration/useHydrate
```jsx
import { useHydrate } from 'react-query/hydration'

useHydrate(dehydratedState)
useHydrate(dehydratedState, options)
```

**Options**

- `dehydratedState: DehydratedState`
- **Required**
- The state to hydrate
- `options: HydrateOptions`
- Optional
- `defaultOptions: QueryOptions`
- The default query options to use for the hydrated queries.
35 changes: 25 additions & 10 deletions src/hydration/hydration.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
import { Query } from '../core/query'
import { QueryCache } from '../core/queryCache'
import { QueryKey } from '../core/types'
import { QueryKey, QueryOptions } from '../core/types'

export interface DehydratedQueryConfig {
// TYPES

export interface DehydrateOptions {
shouldDehydrate?: ShouldDehydrateFunction
}

export interface HydrateOptions {
defaultOptions?: QueryOptions
}

interface DehydratedQueryConfig {
cacheTime: number
}

export interface DehydratedQuery {
interface DehydratedQuery {
queryKey: QueryKey
queryHash: string
data?: unknown
Expand All @@ -20,9 +30,7 @@ export interface DehydratedState {

export type ShouldDehydrateFunction = (query: Query) => boolean

export interface DehydrateConfig {
shouldDehydrate?: ShouldDehydrateFunction
}
// FUNCTIONS

function serializePositiveNumber(value: number): number {
return value === Infinity ? -1 : value
Expand Down Expand Up @@ -54,10 +62,11 @@ function defaultShouldDehydrate(query: Query) {

export function dehydrate(
cache: QueryCache,
dehydrateConfig?: DehydrateConfig
options?: DehydrateOptions
): DehydratedState {
const config = dehydrateConfig || {}
const shouldDehydrate = config.shouldDehydrate || defaultShouldDehydrate
options = options || {}

const shouldDehydrate = options.shouldDehydrate || defaultShouldDehydrate
const queries: DehydratedQuery[] = []

cache.getAll().forEach(query => {
Expand All @@ -69,11 +78,16 @@ export function dehydrate(
return { queries }
}

export function hydrate(cache: QueryCache, dehydratedState: unknown): void {
export function hydrate(
cache: QueryCache,
dehydratedState: unknown,
options?: HydrateOptions
): void {
if (typeof dehydratedState !== 'object' || dehydratedState === null) {
return
}

const defaultOptions = options?.defaultOptions || {}
const queries = (dehydratedState as DehydratedState).queries || []

queries.forEach(dehydratedQuery => {
Expand All @@ -90,6 +104,7 @@ export function hydrate(cache: QueryCache, dehydratedState: unknown): void {
queryKey: dehydratedQuery.queryKey,
queryHash: dehydratedQuery.queryHash,
options: {
...defaultOptions,
cacheTime: deserializePositiveNumber(
dehydratedQuery.config.cacheTime
),
Expand Down
5 changes: 2 additions & 3 deletions src/hydration/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@ export { useHydrate, Hydrate } from './react'

// Types
export type {
DehydratedQueryConfig,
DehydratedQuery,
DehydrateOptions,
DehydratedState,
HydrateOptions,
ShouldDehydrateFunction,
DehydrateConfig,
} from './hydration'
export type { HydrateProps } from './react'
22 changes: 15 additions & 7 deletions src/hydration/react.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,35 @@
import React from 'react'

import { useQueryClient } from '../react'
import { hydrate } from './hydration'
import { hydrate, HydrateOptions } from './hydration'

export function useHydrate(queries: unknown) {
export function useHydrate(state: unknown, options?: HydrateOptions) {
const client = useQueryClient()
const cache = client.getCache()

const optionsRef = React.useRef(options)
optionsRef.current = options

// Running hydrate again with the same queries is safe,
// it wont overwrite or initialize existing queries,
// relying on useMemo here is only a performance optimization
React.useMemo(() => {
if (queries) {
hydrate(cache, queries)
if (state) {
hydrate(cache, state, optionsRef.current)
}
}, [cache, queries])
}, [cache, state])
}

export interface HydrateProps {
state?: unknown
options?: HydrateOptions
}

export const Hydrate: React.FC<HydrateProps> = ({ state, children }) => {
useHydrate(state)
export const Hydrate: React.FC<HydrateProps> = ({
children,
options,
state,
}) => {
useHydrate(state, options)
return children as React.ReactElement<any>
}
14 changes: 14 additions & 0 deletions src/hydration/tests/hydration.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,20 @@ describe('dehydration and rehydration', () => {
hydrationCache.clear()
})

test('should be able to provide default options for the hydrated queries', async () => {
const cache = new QueryCache()
const client = new QueryClient({ cache })
await client.prefetchQuery('string', () => fetchData('string'))
const dehydrated = dehydrate(cache)
const stringified = JSON.stringify(dehydrated)
const parsed = JSON.parse(stringified)
const hydrationCache = new QueryCache()
hydrate(hydrationCache, parsed, { defaultOptions: { retry: 10 } })
expect(hydrationCache.find('string')?.options.retry).toBe(10)
cache.clear()
hydrationCache.clear()
})

test('should work with complex keys', async () => {
const cache = new QueryCache()
const client = new QueryClient({ cache })
Expand Down

0 comments on commit dcb3e7f

Please sign in to comment.