UNPKG

@tanstack/react-query

Version:

Hooks for managing, caching and syncing asynchronous and remote data in React

1 lines 5.18 kB
{"version":3,"file":"HydrationBoundary.cjs","names":["useQueryClient","React"],"sources":["../../src/HydrationBoundary.tsx"],"sourcesContent":["'use client'\nimport * as React from 'react'\n\nimport { hydrate } from '@tanstack/query-core'\nimport { useQueryClient } from './QueryClientProvider'\nimport type {\n DehydratedState,\n HydrateOptions,\n OmitKeyof,\n QueryClient,\n} from '@tanstack/query-core'\n\nexport interface HydrationBoundaryProps {\n state: DehydratedState | null | undefined\n options?: OmitKeyof<HydrateOptions, 'defaultOptions'> & {\n defaultOptions?: OmitKeyof<\n Exclude<HydrateOptions['defaultOptions'], undefined>,\n 'mutations'\n >\n }\n children?: React.ReactNode\n queryClient?: QueryClient\n}\n\nexport const HydrationBoundary = ({\n children,\n options = {},\n state,\n queryClient,\n}: HydrationBoundaryProps) => {\n const client = useQueryClient(queryClient)\n\n const optionsRef = React.useRef(options)\n React.useEffect(() => {\n optionsRef.current = options\n })\n\n // This useMemo is for performance reasons only, everything inside it must\n // be safe to run in every render and code here should be read as \"in render\".\n //\n // This code needs to happen during the render phase, because after initial\n // SSR, hydration needs to happen _before_ children render. Also, if hydrating\n // during a transition, we want to hydrate as much as is safe in render so\n // we can prerender as much as possible.\n //\n // For any queries that already exist in the cache, we want to hold back on\n // hydrating until _after_ the render phase. The reason for this is that during\n // transitions, we don't want the existing queries and observers to update to\n // the new data on the current page, only _after_ the transition is committed.\n // If the transition is aborted, we will have hydrated any _new_ queries, but\n // we throw away the fresh data for any existing ones to avoid unexpectedly\n // updating the UI.\n const hydrationQueue: DehydratedState['queries'] | undefined =\n React.useMemo(() => {\n if (state) {\n if (typeof state !== 'object') {\n return\n }\n\n const queryCache = client.getQueryCache()\n // State is supplied from the outside and we might as well fail\n // gracefully if it has the wrong shape, so while we type `queries`\n // as required, we still provide a fallback.\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const queries = state.queries || []\n\n const newQueries: DehydratedState['queries'] = []\n const existingQueries: DehydratedState['queries'] = []\n for (const dehydratedQuery of queries) {\n const existingQuery = queryCache.get(dehydratedQuery.queryHash)\n\n if (!existingQuery) {\n newQueries.push(dehydratedQuery)\n } else {\n const hydrationIsNewer =\n dehydratedQuery.state.dataUpdatedAt >\n existingQuery.state.dataUpdatedAt ||\n (dehydratedQuery.promise &&\n existingQuery.state.status !== 'pending' &&\n existingQuery.state.fetchStatus !== 'fetching' &&\n dehydratedQuery.dehydratedAt !== undefined &&\n dehydratedQuery.dehydratedAt >\n existingQuery.state.dataUpdatedAt)\n\n if (hydrationIsNewer) {\n existingQueries.push(dehydratedQuery)\n }\n }\n }\n\n if (newQueries.length > 0) {\n // It's actually fine to call this with queries/state that already exists\n // in the cache, or is older. hydrate() is idempotent for queries.\n // eslint-disable-next-line react-hooks/refs\n hydrate(client, { queries: newQueries }, optionsRef.current)\n }\n if (existingQueries.length > 0) {\n return existingQueries\n }\n }\n return undefined\n }, [client, state])\n\n React.useEffect(() => {\n if (hydrationQueue) {\n hydrate(client, { queries: hydrationQueue }, optionsRef.current)\n }\n }, [client, hydrationQueue])\n\n return children as React.ReactElement\n}\n"],"mappings":";;;;;;;;AAwBA,MAAa,qBAAqB,EAChC,UACA,UAAU,CAAC,GACX,OACA,kBAC4B;CAC5B,MAAM,SAASA,4BAAAA,eAAe,WAAW;CAEzC,MAAM,aAAaC,MAAM,OAAO,OAAO;CACvC,MAAM,gBAAgB;EACpB,WAAW,UAAU;CACvB,CAAC;CAiBD,MAAM,iBACJA,MAAM,cAAc;EAClB,IAAI,OAAO;GACT,IAAI,OAAO,UAAU,UACnB;GAGF,MAAM,aAAa,OAAO,cAAc;GAKxC,MAAM,UAAU,MAAM,WAAW,CAAC;GAElC,MAAM,aAAyC,CAAC;GAChD,MAAM,kBAA8C,CAAC;GACrD,KAAK,MAAM,mBAAmB,SAAS;IACrC,MAAM,gBAAgB,WAAW,IAAI,gBAAgB,SAAS;IAE9D,IAAI,CAAC,eACH,WAAW,KAAK,eAAe;SAY/B,IATE,gBAAgB,MAAM,gBACpB,cAAc,MAAM,iBACrB,gBAAgB,WACf,cAAc,MAAM,WAAW,aAC/B,cAAc,MAAM,gBAAgB,cACpC,gBAAgB,iBAAiB,KAAA,KACjC,gBAAgB,eACd,cAAc,MAAM,eAGxB,gBAAgB,KAAK,eAAe;GAG1C;GAEA,IAAI,WAAW,SAAS,GAItB,CAAA,GAAA,qBAAA,QAAA,CAAQ,QAAQ,EAAE,SAAS,WAAW,GAAG,WAAW,OAAO;GAE7D,IAAI,gBAAgB,SAAS,GAC3B,OAAO;EAEX;CAEF,GAAG,CAAC,QAAQ,KAAK,CAAC;CAEpB,MAAM,gBAAgB;EACpB,IAAI,gBACF,CAAA,GAAA,qBAAA,QAAA,CAAQ,QAAQ,EAAE,SAAS,eAAe,GAAG,WAAW,OAAO;CAEnE,GAAG,CAAC,QAAQ,cAAc,CAAC;CAE3B,OAAO;AACT"}