UNPKG

4.03 kBJavaScriptView Raw
1import { __spreadArray } from "tslib";
2import * as React from "rehackt";
3import { useApolloClient } from "./useApolloClient.js";
4import { getSuspenseCache, unwrapQueryRef, updateWrappedQueryRef, wrapQueryRef, } from "../internal/index.js";
5import { wrapHook } from "./internal/index.js";
6import { useWatchQueryOptions } from "./useSuspenseQuery.js";
7import { canonicalStringify } from "../../cache/index.js";
8export function useBackgroundQuery(query, options) {
9 if (options === void 0) { options = Object.create(null); }
10 return wrapHook("useBackgroundQuery", _useBackgroundQuery, useApolloClient(typeof options === "object" ? options.client : undefined))(query, options);
11}
12function _useBackgroundQuery(query, options) {
13 var client = useApolloClient(options.client);
14 var suspenseCache = getSuspenseCache(client);
15 var watchQueryOptions = useWatchQueryOptions({ client: client, query: query, options: options });
16 var fetchPolicy = watchQueryOptions.fetchPolicy, variables = watchQueryOptions.variables;
17 var _a = options.queryKey, queryKey = _a === void 0 ? [] : _a;
18 // This ref tracks the first time query execution is enabled to determine
19 // whether to return a query ref or `undefined`. When initialized
20 // in a skipped state (either via `skip: true` or `skipToken`) we return
21 // `undefined` for the `queryRef` until the query has been enabled. Once
22 // enabled, a query ref is always returned regardless of whether the query is
23 // skipped again later.
24 var didFetchResult = React.useRef(fetchPolicy !== "standby");
25 didFetchResult.current || (didFetchResult.current = fetchPolicy !== "standby");
26 var cacheKey = __spreadArray([
27 query,
28 canonicalStringify(variables)
29 ], [].concat(queryKey), true);
30 var queryRef = suspenseCache.getQueryRef(cacheKey, function () {
31 return client.watchQuery(watchQueryOptions);
32 });
33 var _b = React.useState(wrapQueryRef(queryRef)), wrappedQueryRef = _b[0], setWrappedQueryRef = _b[1];
34 if (unwrapQueryRef(wrappedQueryRef) !== queryRef) {
35 setWrappedQueryRef(wrapQueryRef(queryRef));
36 }
37 if (queryRef.didChangeOptions(watchQueryOptions)) {
38 var promise = queryRef.applyOptions(watchQueryOptions);
39 updateWrappedQueryRef(wrappedQueryRef, promise);
40 }
41 // This prevents issues where rerendering useBackgroundQuery after the
42 // queryRef has been disposed would cause the hook to return a new queryRef
43 // instance since disposal also removes it from the suspense cache. We add
44 // the queryRef back in the suspense cache so that the next render will reuse
45 // this queryRef rather than initializing a new instance.
46 React.useEffect(function () {
47 // Since the queryRef is disposed async via `setTimeout`, we have to wait a
48 // tick before checking it and adding back to the suspense cache.
49 var id = setTimeout(function () {
50 if (queryRef.disposed) {
51 suspenseCache.add(cacheKey, queryRef);
52 }
53 });
54 return function () { return clearTimeout(id); };
55 // Omitting the deps is intentional. This avoids stale closures and the
56 // conditional ensures we aren't running the logic on each render.
57 });
58 var fetchMore = React.useCallback(function (options) {
59 var promise = queryRef.fetchMore(options);
60 setWrappedQueryRef(wrapQueryRef(queryRef));
61 return promise;
62 }, [queryRef]);
63 var refetch = React.useCallback(function (variables) {
64 var promise = queryRef.refetch(variables);
65 setWrappedQueryRef(wrapQueryRef(queryRef));
66 return promise;
67 }, [queryRef]);
68 React.useEffect(function () { return queryRef.softRetain(); }, [queryRef]);
69 return [
70 didFetchResult.current ? wrappedQueryRef : void 0,
71 {
72 fetchMore: fetchMore,
73 refetch: refetch,
74 subscribeToMore: queryRef.observable.subscribeToMore,
75 },
76 ];
77}
78//# sourceMappingURL=useBackgroundQuery.js.map
\No newline at end of file