UNPKG

3.71 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'use strict';
12
13var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
14
15var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread"));
16
17var areEqual = require("fbjs/lib/areEqual");
18
19var useRelayEnvironment = require('./useRelayEnvironment');
20
21var _require = require('react'),
22 useEffect = _require.useEffect,
23 useState = _require.useState;
24
25/**
26 * Public hook for consuming the results of `@connection_resolver` and
27 * `@stream_connection_resolver`. Given a resolver and a reference to a
28 * connection, returns the latest results for that connection as derived by
29 * that resolver.
30 */
31function useConnection(resolver, ref) {
32 var _connectionState$refe;
33
34 var environment = useRelayEnvironment();
35 var reference = ref === null || ref === void 0 ? void 0 : ref.__connection; // Lazily initialize state, resetting if the inputs change
36
37 var _useState = useState(function () {
38 return buildConnectionState(environment, resolver, reference, null);
39 }),
40 connectionState = _useState[0],
41 setConnectionState = _useState[1];
42
43 if (connectionState.environment !== environment || ((_connectionState$refe = connectionState.reference) === null || _connectionState$refe === void 0 ? void 0 : _connectionState$refe.id) !== (reference === null || reference === void 0 ? void 0 : reference.id) || connectionState.resolver !== resolver) {
44 setConnectionState(buildConnectionState(environment, resolver, reference, connectionState));
45 }
46
47 var connectionSnapshot = connectionState.snapshot;
48 useEffect(function () {
49 if (connectionSnapshot == null) {
50 return;
51 }
52
53 var latestState = buildConnectionState(environment, resolver, reference, connectionState);
54
55 if (latestState.snapshot != null && !areEqual(latestState.snapshot.state, connectionSnapshot.state)) {
56 setConnectionState(latestState); // as an optimization, avoid subscribing until a render with fresh data
57
58 return;
59 }
60
61 var store = environment.getStore();
62 var disposable = store.subscribeConnection_UNSTABLE(connectionSnapshot, resolver, function (updatedSnapshot) {
63 setConnectionState(function (currentConnectionState) {
64 if (currentConnectionState.generation !== connectionState.generation) {
65 // When the connection generation changes there can be a gap where
66 // the previous generation is still subscribed (between rendering
67 // w the new identity and the effect cleanup). Ignore these updates.
68 return currentConnectionState;
69 }
70
71 return (0, _objectSpread2["default"])({}, currentConnectionState, {
72 snapshot: updatedSnapshot
73 });
74 });
75 });
76 return function () {
77 return disposable.dispose();
78 }; // State.generation changes whenever environment/resolver/reference change
79 // eslint-disable-next-line react-hooks/exhaustive-deps
80 }, [connectionState.generation]);
81 return connectionSnapshot != null ? connectionSnapshot.state : connectionSnapshot;
82}
83
84function buildConnectionState(environment, resolver, reference, previousState) {
85 var store = environment.getStore();
86 var snapshot = reference != null ? store.lookupConnection_UNSTABLE(reference, resolver) : null;
87 return {
88 environment: environment,
89 generation: previousState != null ? previousState.generation + 1 : 0,
90 reference: reference,
91 resolver: resolver,
92 snapshot: snapshot
93 };
94}
95
96module.exports = useConnection;
\No newline at end of file