UNPKG

@apollo/client

Version:

A fully-featured caching GraphQL client.

54 lines 2.66 kB
import * as React from "react"; import { useDeepMemo, wrapHook } from "./internal/index.js"; import { useApolloClient } from "./useApolloClient.js"; import { useSyncExternalStore } from "./useSyncExternalStore.js"; export function useFragment(options) { "use no memo"; return wrapHook("useFragment", useFragment_, useApolloClient(options.client))(options); } function useFragment_(options) { const client = useApolloClient(options.client); const { from, ...rest } = options; const { cache } = client; // We calculate the cache id seperately because we don't want changes to non // key fields in the `from` property to recreate the observable. If the cache // identifier stays the same between renders, we want to reuse the existing // subscription. const ids = useDeepMemo(() => { const fromArray = Array.isArray(from) ? from : [from]; const ids = fromArray.map((value) => typeof value === "string" ? value : value === null ? null : cache.identify(value)); return Array.isArray(from) ? ids : ids[0]; }, [cache, from]); const stableOptions = useDeepMemo(() => ({ ...rest, from: ids }), [rest, ids]); const observable = React.useMemo(() => client.watchFragment(stableOptions), [client, stableOptions]); // Unfortunately we forgot to update the use case of `from: null` on // useFragment in 4.0 to match `useSuspenseFragment`. As such, we need to // fallback to data: {} with complete: false when `from` is `null` to maintain // backwards compatibility. We should plan to change this in v5. const getSnapshot = React.useCallback(() => (from === null ? nullResult : observable.getCurrentResult()), [from, observable]); return useSyncExternalStore(React.useCallback((update) => { let lastTimeout = 0; const subscription = observable.subscribe({ next: () => { // If we get another update before we've re-rendered, bail out of // the update and try again. This ensures that the relative timing // between useQuery and useFragment stays roughly the same as // fixed in https://github.com/apollographql/apollo-client/pull/11083 clearTimeout(lastTimeout); lastTimeout = setTimeout(update); }, }); return () => { subscription.unsubscribe(); clearTimeout(lastTimeout); }; }, [observable]), getSnapshot, getSnapshot); } const nullResult = Object.freeze({ data: {}, dataState: "partial", complete: false, }); //# sourceMappingURL=useFragment.js.map