diff --git a/docs/react/guides/migrating-to-v5.md b/docs/react/guides/migrating-to-v5.md index 236dab2c8a..453e51aa30 100644 --- a/docs/react/guides/migrating-to-v5.md +++ b/docs/react/guides/migrating-to-v5.md @@ -300,6 +300,15 @@ However, refetching all pages might lead to UI inconsistencies. Also, this optio The v5 includes a new `maxPages` option for infinite queries to limit the number of pages to store in the query data and to refetch. This new feature handles the use cases initially identified for the `refetchPage` page feature without the related issues. +### New hydration API + +The options you can pass to dehydrate have been simplified. Queries and Mutations are always dehydrated (according to the default function implementation). To change this behaviour, you can implement `shouldDehydrateQuery` or `shouldDehydrateMutation`. + +```diff +- dehydrateMutations?: boolean +- dehydrateQueries?: boolean +``` + ### Infinite queries now need a `defaultPageParam` Previously, we've passed `undefined` to the `queryFn` as `pageParam`, and you could assign a default value to the `pageParam` parameter in the `queryFn` function signature. This had the drawback of storing `undefined` in the `queryCache`, which is not serializable. @@ -410,7 +419,7 @@ We have a new, simplified way to perform optimistic updates by leveraging the re Here, we are only changing how the UI looks when the mutation is running instead of writing data directly to the cache. This works best if we only have one place where we need to show the optimistic update. For more details, have a look at the [optimistic updates documentation](../guides/optimistic-updates.md). -### Eternal list: scalable infinite query with new maxPages option +### Limited, Infinite Queries with new maxPages option Infinite queries are great when infinite scroll or pagination are needed. However, the more pages you fetch, the more memory you consume, and this also slows down the query refetching process as all the pages are sequentially refetched. diff --git a/docs/react/reference/hydration.md b/docs/react/reference/hydration.md index ee657a37cb..48b839f325 100644 --- a/docs/react/reference/hydration.md +++ b/docs/react/reference/hydration.md @@ -12,6 +12,7 @@ import { dehydrate } from '@tanstack/react-query' const dehydratedState = dehydrate(queryClient, { shouldDehydrateQuery, + shouldDehydrateMutation, }) ``` @@ -22,24 +23,20 @@ const dehydratedState = dehydrate(queryClient, { - The `queryClient` that should be dehydrated - `options: DehydrateOptions` - Optional - - `dehydrateMutations: boolean` - - Optional - - Whether or not to dehydrate mutations. - - `dehydrateQueries: boolean` - - Optional - - Whether or not to dehydrate queries. - `shouldDehydrateMutation: (mutation: Mutation) => boolean` - Optional - - This function is called for each mutation in the cache - - Return `true` to include this mutation in dehydration, or `false` otherwise - - The default version only includes paused mutations - - If you would like to extend the function while retaining the previous behavior, import and execute `defaultShouldDehydrateMutation` as part of the return statement - - `shouldDehydrateQuery: (query: Query) => boolean` + - Whether to dehydrate mutations. + - The function is called for each mutation in the cache + - Return `true` to include this mutation in dehydration, or `false` otherwise + - Defaults to only including paused mutations + - If you would like to extend the function while retaining the default behavior, import and execute `defaultShouldDehydrateMutation` as part of the return statement + - `shouldDehydrateQuery: boolean | (query: Query) => boolean` - Optional - - This function is called for each query in the cache - - Return `true` to include this query in dehydration, or `false` otherwise - - The default version only includes successful queries, do `shouldDehydrateQuery: () => true` to include all queries - - If you would like to extend the function while retaining the previous behavior, import and execute `defaultShouldDehydrateQuery` as part of the return statement + - Whether to dehydrate queries. + - The function, it is called for each query in the cache + - Return `true` to include this query in dehydration, or `false` otherwise + - Defaults to only including successful queries + - If you would like to extend the function while retaining the default behavior, import and execute `defaultShouldDehydrateQuery` as part of the return statement **Returns** diff --git a/packages/query-core/src/hydration.ts b/packages/query-core/src/hydration.ts index 6191f7f1e8..dbbd0270f6 100644 --- a/packages/query-core/src/hydration.ts +++ b/packages/query-core/src/hydration.ts @@ -11,10 +11,8 @@ import type { Mutation, MutationState } from './mutation' // TYPES export interface DehydrateOptions { - dehydrateMutations?: boolean - dehydrateQueries?: boolean - shouldDehydrateMutation?: ShouldDehydrateMutationFunction - shouldDehydrateQuery?: ShouldDehydrateQueryFunction + shouldDehydrateMutation?: (mutation: Mutation) => boolean + shouldDehydrateQuery?: (query: Query) => boolean } export interface HydrateOptions { @@ -40,10 +38,6 @@ export interface DehydratedState { queries: DehydratedQuery[] } -export type ShouldDehydrateQueryFunction = (query: Query) => boolean - -export type ShouldDehydrateMutationFunction = (mutation: Mutation) => boolean - // FUNCTIONS function dehydrateMutation(mutation: Mutation): DehydratedMutation { @@ -77,36 +71,23 @@ export function dehydrate( client: QueryClient, options: DehydrateOptions = {}, ): DehydratedState { - const mutations: DehydratedMutation[] = [] - const queries: DehydratedQuery[] = [] - - if (options.dehydrateMutations !== false) { - const shouldDehydrateMutation = - options.shouldDehydrateMutation || defaultShouldDehydrateMutation - - client - .getMutationCache() - .getAll() - .forEach((mutation) => { - if (shouldDehydrateMutation(mutation)) { - mutations.push(dehydrateMutation(mutation)) - } - }) - } + const filterMutation = + options.shouldDehydrateMutation ?? defaultShouldDehydrateMutation + + const mutations = client + .getMutationCache() + .getAll() + .flatMap((mutation) => + filterMutation(mutation) ? [dehydrateMutation(mutation)] : [], + ) - if (options.dehydrateQueries !== false) { - const shouldDehydrateQuery = - options.shouldDehydrateQuery || defaultShouldDehydrateQuery - - client - .getQueryCache() - .getAll() - .forEach((query) => { - if (shouldDehydrateQuery(query)) { - queries.push(dehydrateQuery(query)) - } - }) - } + const filterQuery = + options.shouldDehydrateQuery ?? defaultShouldDehydrateQuery + + const queries = client + .getQueryCache() + .getAll() + .flatMap((query) => (filterQuery(query) ? [dehydrateQuery(query)] : [])) return { mutations, queries } } diff --git a/packages/query-core/src/index.ts b/packages/query-core/src/index.ts index b3012272e9..23a9b44681 100644 --- a/packages/query-core/src/index.ts +++ b/packages/query-core/src/index.ts @@ -23,8 +23,8 @@ export { isCancelledError } from './retryer' export { dehydrate, hydrate, - defaultShouldDehydrateMutation, defaultShouldDehydrateQuery, + defaultShouldDehydrateMutation, } from './hydration' // Types @@ -35,6 +35,4 @@ export type { DehydrateOptions, DehydratedState, HydrateOptions, - ShouldDehydrateMutationFunction, - ShouldDehydrateQueryFunction, } from './hydration' diff --git a/packages/query-core/src/tests/hydration.test.tsx b/packages/query-core/src/tests/hydration.test.tsx index 9093c39671..a1c759858a 100644 --- a/packages/query-core/src/tests/hydration.test.tsx +++ b/packages/query-core/src/tests/hydration.test.tsx @@ -113,7 +113,9 @@ describe('dehydration and rehydration', () => { queryFn: () => fetchData('string'), }) - const dehydrated = dehydrate(queryClient, { dehydrateQueries: false }) + const dehydrated = dehydrate(queryClient, { + shouldDehydrateQuery: () => false, + }) expect(dehydrated.queries.length).toBe(0) @@ -244,7 +246,7 @@ describe('dehydration and rehydration', () => { consoleMock.mockRestore() }) - test('should filter queries via shouldDehydrateQuery', async () => { + test('should filter queries via dehydrateQuery', async () => { const queryCache = new QueryCache() const queryClient = createQueryClient({ queryCache }) await queryClient.prefetchQuery({ @@ -446,7 +448,9 @@ describe('dehydration and rehydration', () => { ).catch(() => undefined) await sleep(1) - const dehydrated = dehydrate(queryClient, { dehydrateMutations: false }) + const dehydrated = dehydrate(queryClient, { + shouldDehydrateMutation: () => false, + }) expect(dehydrated.mutations.length).toBe(0)