UNPKG

5.22 kBJavaScriptView Raw
1/**
2 * Copyright (c) Facebook, Inc. and its affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 *
7 * @emails oncall+relay
8 *
9 * @format
10 */
11// flowlint ambiguous-object-type:error
12'use strict';
13
14var invariant = require("fbjs/lib/invariant");
15
16var useLazyLoadQueryNode = require('./useLazyLoadQueryNode');
17
18var useMemoOperationDescriptor = require('./useMemoOperationDescriptor');
19
20var useRelayEnvironment = require('./useRelayEnvironment');
21
22var warning = require("fbjs/lib/warning");
23
24var _require = require('./loadQuery'),
25 useTrackLoadQueryInRender = _require.useTrackLoadQueryInRender;
26
27var _require2 = require('react'),
28 useDebugValue = _require2.useDebugValue;
29
30var _require3 = require('relay-runtime'),
31 fetchQueryDeduped = _require3.__internal.fetchQueryDeduped,
32 Observable = _require3.Observable;
33
34function usePreloadedQuery(gqlQuery, preloadedQuery, options) {
35 // We need to use this hook in order to be able to track if
36 // loadQuery was called during render
37 useTrackLoadQueryInRender();
38 var environment = useRelayEnvironment();
39 var fetchPolicy = preloadedQuery.fetchPolicy,
40 source = preloadedQuery.source,
41 variables = preloadedQuery.variables;
42 var operation = useMemoOperationDescriptor(gqlQuery, variables);
43 var useLazyLoadQueryNodeParams;
44
45 if (preloadedQuery.kind === 'PreloadedQuery_DEPRECATED') {
46 var fetchKey = preloadedQuery.fetchKey;
47 !(operation.request.node.params.name === preloadedQuery.name) ? process.env.NODE_ENV !== "production" ? invariant(false, 'usePreloadedQuery(): Expected data to be prefetched for query `%s`, ' + 'got prefetch results for query `%s`.', operation.request.node.params.name, preloadedQuery.name) : invariant(false) : void 0;
48 useLazyLoadQueryNodeParams = {
49 componentDisplayName: 'usePreloadedQuery()',
50 fetchKey: fetchKey,
51 fetchObservable: fetchQueryDeduped(environment, operation.request.identifier, function () {
52 if (environment === preloadedQuery.environment && source != null) {
53 return environment.executeWithSource({
54 operation: operation,
55 source: source
56 });
57 } else {
58 return environment.execute({
59 operation: operation
60 });
61 }
62 }),
63 fetchPolicy: fetchPolicy,
64 query: operation,
65 renderPolicy: options === null || options === void 0 ? void 0 : options.UNSTABLE_renderPolicy
66 };
67 } else {
68 // Here, we are calling fetchQueryDeduped, which usually ensures that only
69 // a single network request is active for a given (environment, identifier) pair.
70 // If no network request is active, it will call the third argument and initiate
71 // a network request.
72 //
73 // However, if preloadedQuery.kind === 'PreloadedQuery', the network request (if
74 // it exists) has already been made.
75 //
76 // Thus, if two calls to loadQuery are made with the same environment and identifier
77 // (i.e. the same request is made twice), the second query will be deduped
78 // and components will suspend for the duration of the first query.
79 var dedupedSource = fetchQueryDeduped(environment, operation.request.identifier, function () {
80 if (source && environment === preloadedQuery.environment) {
81 return source.ifEmpty(Observable.create(function (sink) {
82 return environment.execute({
83 operation: operation
84 }).subscribe(sink);
85 }));
86 } else {
87 // if a call to loadQuery is made with a particular environment, and that
88 // preloaded query is passed to usePreloadedQuery in a different environmental
89 // context, we cannot re-use the existing preloaded query. Instead, we must
90 // re-execute the query with the new environment (at render time.)
91 // TODO T68036756 track occurences of this warning and turn it into a hard error
92 process.env.NODE_ENV !== "production" ? warning(false, 'usePreloadedQuery(): usePreloadedQuery was passed a preloaded query ' + 'that was created with a different environment than the one that is currently ' + 'in context. In the future, this will become a hard error.') : void 0;
93 return environment.execute({
94 operation: operation
95 });
96 }
97 });
98 useLazyLoadQueryNodeParams = {
99 componentDisplayName: 'usePreloadedQuery()',
100 fetchObservable: dedupedSource,
101 fetchPolicy: fetchPolicy,
102 query: operation,
103 renderPolicy: options === null || options === void 0 ? void 0 : options.UNSTABLE_renderPolicy
104 };
105 }
106
107 var data = useLazyLoadQueryNode(useLazyLoadQueryNodeParams);
108
109 if (process.env.NODE_ENV !== "production") {
110 // eslint-disable-next-line react-hooks/rules-of-hooks
111 useDebugValue({
112 query: preloadedQuery.name,
113 variables: preloadedQuery.variables,
114 data: data,
115 fetchKey: preloadedQuery.kind === 'PreloadedQuery_DEPRECATED' ? preloadedQuery.fetchKey : undefined,
116 fetchPolicy: fetchPolicy,
117 renderPolicy: options === null || options === void 0 ? void 0 : options.UNSTABLE_renderPolicy
118 });
119 }
120
121 return data;
122}
123
124module.exports = usePreloadedQuery;
\No newline at end of file