UNPKG

5.84 kBJavaScriptView Raw
1function _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); }
2
3import { ApolloError } from 'apollo-client';
4import { useContext, useEffect, useMemo, useState } from 'react';
5import { useApolloClient } from './ApolloContext';
6import { SSRContext } from './internal/SSRContext';
7import actHack from './internal/actHack';
8import { getCachedObservableQuery, invalidateCachedObservableQuery } from './queryCache';
9import { compact, objToKey } from './utils';
10export function useQuery(query, _temp) {
11 var _ref = _temp === void 0 ? {} : _temp,
12 _ref$ssr = _ref.ssr,
13 ssr = _ref$ssr === void 0 ? true : _ref$ssr,
14 _ref$skip = _ref.skip,
15 skip = _ref$skip === void 0 ? false : _ref$skip,
16 _ref$suspend = _ref.suspend,
17 suspend = _ref$suspend === void 0 ? false : _ref$suspend,
18 pollInterval = _ref.pollInterval,
19 _ref$notifyOnNetworkS = _ref.notifyOnNetworkStatusChange,
20 notifyOnNetworkStatusChange = _ref$notifyOnNetworkS === void 0 ? false : _ref$notifyOnNetworkS,
21 overrideClient = _ref.client,
22 context = _ref.context,
23 metadata = _ref.metadata,
24 variables = _ref.variables,
25 actualCachePolicy = _ref.fetchPolicy,
26 errorPolicy = _ref.errorPolicy,
27 fetchResults = _ref.fetchResults;
28
29 var client = useApolloClient(overrideClient);
30 var ssrManager = useContext(SSRContext);
31 var ssrInUse = ssr && ssrManager; // Skips when `skip: true` or SSRContext passed but `ssr: false`
32
33 var shouldSkip = skip || ssrManager != null && !ssr;
34 var fetchPolicy = ssrInUse && ( // Taken from https://github.com/apollographql/react-apollo/blob/2d7e48b7d0c26e792e1ed26e98bb84d8fba5bb8a/src/Query.tsx#L167-L169
35 actualCachePolicy === 'network-only' || actualCachePolicy === 'cache-and-network') ? 'cache-first' : actualCachePolicy;
36 var watchQueryOptions = useMemo(function () {
37 return compact({
38 context: context,
39 errorPolicy: errorPolicy,
40 fetchPolicy: fetchPolicy,
41 fetchResults: fetchResults,
42 metadata: metadata,
43 notifyOnNetworkStatusChange: notifyOnNetworkStatusChange,
44 pollInterval: pollInterval,
45 query: query,
46 variables: variables
47 });
48 }, [query, pollInterval, notifyOnNetworkStatusChange, context && objToKey(context), metadata && objToKey(metadata), variables && objToKey(variables), fetchPolicy, errorPolicy, fetchResults]);
49 var observableQuery = useMemo(function () {
50 return getCachedObservableQuery(client, watchQueryOptions);
51 }, [client, watchQueryOptions]);
52
53 var _useState = useState(0),
54 responseId = _useState[0],
55 setResponseId = _useState[1];
56
57 var currentResult = useMemo(function () {
58 var helpers = {
59 fetchMore: observableQuery.fetchMore.bind(observableQuery),
60 refetch: observableQuery.refetch.bind(observableQuery),
61 startPolling: observableQuery.startPolling.bind(observableQuery),
62 stopPolling: observableQuery.stopPolling.bind(observableQuery),
63 updateQuery: observableQuery.updateQuery.bind(observableQuery)
64 };
65 var result = observableQuery.getCurrentResult(); // return the old result data when there is an error
66
67 var data = result.data;
68
69 if (result.error || result.errors) {
70 data = _extends({}, result.data, {}, (observableQuery.getLastResult() || {}).data);
71 }
72
73 if (shouldSkip) {
74 // Taken from https://github.com/apollographql/react-apollo/blob/5cb63b3625ce5e4a3d3e4ba132eaec2a38ef5d90/src/Query.tsx#L376-L381
75 return _extends({}, helpers, {
76 data: undefined,
77 error: undefined,
78 loading: false,
79 networkStatus: undefined
80 });
81 }
82
83 return _extends({}, helpers, {
84 data: data,
85 error: result.errors && result.errors.length > 0 ? new ApolloError({
86 graphQLErrors: result.errors
87 }) : result.error,
88 errors: result.errors,
89 loading: result.loading,
90 // don't try to return `networkStatus` when suspense it's used
91 // because it's unreliable in that case
92 // https://github.com/trojanowski/react-apollo-hooks/pull/68
93 networkStatus: suspend ? undefined : result.networkStatus,
94 partial: result.partial,
95 stale: result.stale
96 });
97 }, [shouldSkip, responseId, observableQuery]);
98 useEffect(function () {
99 if (shouldSkip) {
100 return;
101 }
102
103 var invalidateCurrentResult = function invalidateCurrentResult() {
104 // A hack to get rid React warnings during tests. The default
105 // implementation of `actHack` just invokes the callback immediately.
106 // In tests, it's replaced with `act` from react-testing-library.
107 // A better solution welcome.
108 actHack(function () {
109 setResponseId(function (x) {
110 return x + 1;
111 });
112 });
113 };
114
115 var subscription = observableQuery.subscribe(invalidateCurrentResult, invalidateCurrentResult);
116 invalidateCachedObservableQuery(client, watchQueryOptions);
117 return function () {
118 subscription.unsubscribe();
119 };
120 }, [shouldSkip, observableQuery]);
121 ensureSupportedFetchPolicy(suspend, fetchPolicy);
122
123 if (currentResult.partial) {
124 if (suspend) {
125 // throw a promise - use the react suspense to wait until the data is
126 // available
127 throw observableQuery.result();
128 }
129
130 if (ssrInUse) {
131 ssrManager.register(observableQuery.result());
132 }
133 }
134
135 return currentResult;
136}
137
138function ensureSupportedFetchPolicy(suspend, fetchPolicy) {
139 if (suspend && fetchPolicy && fetchPolicy !== 'cache-first') {
140 throw new Error("Fetch policy " + fetchPolicy + " is not supported without 'suspend: false'");
141 }
142}
\No newline at end of file