UNPKG

react-apollo-hooks

Version:

Use [Apollo Client](https://github.com/apollographql/apollo-client) as React [hooks](https://reactjs.org/docs/hooks-intro.html).

142 lines (127 loc) 5.84 kB
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } import { ApolloError } from 'apollo-client'; import { useContext, useEffect, useMemo, useState } from 'react'; import { useApolloClient } from './ApolloContext'; import { SSRContext } from './internal/SSRContext'; import actHack from './internal/actHack'; import { getCachedObservableQuery, invalidateCachedObservableQuery } from './queryCache'; import { compact, objToKey } from './utils'; export function useQuery(query, _temp) { var _ref = _temp === void 0 ? {} : _temp, _ref$ssr = _ref.ssr, ssr = _ref$ssr === void 0 ? true : _ref$ssr, _ref$skip = _ref.skip, skip = _ref$skip === void 0 ? false : _ref$skip, _ref$suspend = _ref.suspend, suspend = _ref$suspend === void 0 ? false : _ref$suspend, pollInterval = _ref.pollInterval, _ref$notifyOnNetworkS = _ref.notifyOnNetworkStatusChange, notifyOnNetworkStatusChange = _ref$notifyOnNetworkS === void 0 ? false : _ref$notifyOnNetworkS, overrideClient = _ref.client, context = _ref.context, metadata = _ref.metadata, variables = _ref.variables, actualCachePolicy = _ref.fetchPolicy, errorPolicy = _ref.errorPolicy, fetchResults = _ref.fetchResults; var client = useApolloClient(overrideClient); var ssrManager = useContext(SSRContext); var ssrInUse = ssr && ssrManager; // Skips when `skip: true` or SSRContext passed but `ssr: false` var shouldSkip = skip || ssrManager != null && !ssr; var fetchPolicy = ssrInUse && ( // Taken from https://github.com/apollographql/react-apollo/blob/2d7e48b7d0c26e792e1ed26e98bb84d8fba5bb8a/src/Query.tsx#L167-L169 actualCachePolicy === 'network-only' || actualCachePolicy === 'cache-and-network') ? 'cache-first' : actualCachePolicy; var watchQueryOptions = useMemo(function () { return compact({ context: context, errorPolicy: errorPolicy, fetchPolicy: fetchPolicy, fetchResults: fetchResults, metadata: metadata, notifyOnNetworkStatusChange: notifyOnNetworkStatusChange, pollInterval: pollInterval, query: query, variables: variables }); }, [query, pollInterval, notifyOnNetworkStatusChange, context && objToKey(context), metadata && objToKey(metadata), variables && objToKey(variables), fetchPolicy, errorPolicy, fetchResults]); var observableQuery = useMemo(function () { return getCachedObservableQuery(client, watchQueryOptions); }, [client, watchQueryOptions]); var _useState = useState(0), responseId = _useState[0], setResponseId = _useState[1]; var currentResult = useMemo(function () { var helpers = { fetchMore: observableQuery.fetchMore.bind(observableQuery), refetch: observableQuery.refetch.bind(observableQuery), startPolling: observableQuery.startPolling.bind(observableQuery), stopPolling: observableQuery.stopPolling.bind(observableQuery), updateQuery: observableQuery.updateQuery.bind(observableQuery) }; var result = observableQuery.getCurrentResult(); // return the old result data when there is an error var data = result.data; if (result.error || result.errors) { data = _extends({}, result.data, {}, (observableQuery.getLastResult() || {}).data); } if (shouldSkip) { // Taken from https://github.com/apollographql/react-apollo/blob/5cb63b3625ce5e4a3d3e4ba132eaec2a38ef5d90/src/Query.tsx#L376-L381 return _extends({}, helpers, { data: undefined, error: undefined, loading: false, networkStatus: undefined }); } return _extends({}, helpers, { data: data, error: result.errors && result.errors.length > 0 ? new ApolloError({ graphQLErrors: result.errors }) : result.error, errors: result.errors, loading: result.loading, // don't try to return `networkStatus` when suspense it's used // because it's unreliable in that case // https://github.com/trojanowski/react-apollo-hooks/pull/68 networkStatus: suspend ? undefined : result.networkStatus, partial: result.partial, stale: result.stale }); }, [shouldSkip, responseId, observableQuery]); useEffect(function () { if (shouldSkip) { return; } var invalidateCurrentResult = function invalidateCurrentResult() { // A hack to get rid React warnings during tests. The default // implementation of `actHack` just invokes the callback immediately. // In tests, it's replaced with `act` from react-testing-library. // A better solution welcome. actHack(function () { setResponseId(function (x) { return x + 1; }); }); }; var subscription = observableQuery.subscribe(invalidateCurrentResult, invalidateCurrentResult); invalidateCachedObservableQuery(client, watchQueryOptions); return function () { subscription.unsubscribe(); }; }, [shouldSkip, observableQuery]); ensureSupportedFetchPolicy(suspend, fetchPolicy); if (currentResult.partial) { if (suspend) { // throw a promise - use the react suspense to wait until the data is // available throw observableQuery.result(); } if (ssrInUse) { ssrManager.register(observableQuery.result()); } } return currentResult; } function ensureSupportedFetchPolicy(suspend, fetchPolicy) { if (suspend && fetchPolicy && fetchPolicy !== 'cache-first') { throw new Error("Fetch policy " + fetchPolicy + " is not supported without 'suspend: false'"); } }