UNPKG

@apollo/client

Version:

A fully-featured caching GraphQL client.

79 lines (78 loc) 4.12 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useBackgroundQuery = useBackgroundQuery; const tslib_1 = require("tslib"); const React = tslib_1.__importStar(require("react")); const internal_1 = require("@apollo/client/react/internal"); const index_js_1 = require("./internal/index.cjs"); const useApolloClient_js_1 = require("./useApolloClient.cjs"); const useSuspenseQuery_js_1 = require("./useSuspenseQuery.cjs"); function useBackgroundQuery(query, options) { "use no memo"; return (0, index_js_1.wrapHook)("useBackgroundQuery", // eslint-disable-next-line react-compiler/react-compiler useBackgroundQuery_, (0, useApolloClient_js_1.useApolloClient)(typeof options === "object" ? options.client : undefined))(query, options ?? {}); } function useBackgroundQuery_(query, options) { const client = (0, useApolloClient_js_1.useApolloClient)(options.client); const suspenseCache = (0, internal_1.getSuspenseCache)(client); const watchQueryOptions = (0, useSuspenseQuery_js_1.useWatchQueryOptions)({ client, query, options }); const { fetchPolicy } = watchQueryOptions; const cacheKey = (0, index_js_1.useSuspenseHookCacheKey)(query, options); // This ref tracks the first time query execution is enabled to determine // whether to return a query ref or `undefined`. When initialized // in a skipped state (either via `skip: true` or `skipToken`) we return // `undefined` for the `queryRef` until the query has been enabled. Once // enabled, a query ref is always returned regardless of whether the query is // skipped again later. const didFetchResult = React.useRef(fetchPolicy !== "standby"); didFetchResult.current ||= fetchPolicy !== "standby"; const queryRef = suspenseCache.getQueryRef(cacheKey, () => client.watchQuery(watchQueryOptions)); const [wrappedQueryRef, setWrappedQueryRef] = React.useState((0, internal_1.wrapQueryRef)(queryRef)); if ((0, internal_1.unwrapQueryRef)(wrappedQueryRef) !== queryRef) { setWrappedQueryRef((0, internal_1.wrapQueryRef)(queryRef)); } if (queryRef.didChangeOptions(watchQueryOptions)) { const promise = queryRef.applyOptions(watchQueryOptions); (0, internal_1.updateWrappedQueryRef)(wrappedQueryRef, promise); } // This prevents issues where rerendering useBackgroundQuery after the // queryRef has been disposed would cause the hook to return a new queryRef // instance since disposal also removes it from the suspense cache. We add // the queryRef back in the suspense cache so that the next render will reuse // this queryRef rather than initializing a new instance. React.useEffect(() => { // Since the queryRef is disposed async via `setTimeout`, we have to wait a // tick before checking it and adding back to the suspense cache. const id = setTimeout(() => { if (queryRef.disposed) { suspenseCache.add(cacheKey, queryRef); } }); return () => clearTimeout(id); // Omitting the deps is intentional. This avoids stale closures and the // conditional ensures we aren't running the logic on each render. }); const fetchMore = React.useCallback((options) => { const promise = queryRef.fetchMore(options); setWrappedQueryRef((0, internal_1.wrapQueryRef)(queryRef)); return promise; }, [queryRef]); const refetch = React.useCallback((variables) => { const promise = queryRef.refetch(variables); setWrappedQueryRef((0, internal_1.wrapQueryRef)(queryRef)); return promise; }, [queryRef]); React.useEffect(() => queryRef.softRetain(), [queryRef]); return [ didFetchResult.current ? wrappedQueryRef : void 0, { fetchMore, refetch, // TODO: The internalQueryRef doesn't have TVariables' type information so we have to cast it here subscribeToMore: queryRef.observable .subscribeToMore, }, ]; } //# sourceMappingURL=useBackgroundQuery.cjs.map