UNPKG

2.96 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 *
8 * @format
9 */
10// flowlint ambiguous-object-type:error
11'use strict';
12
13var React = require('react');
14
15var ReactRelayContext = require('./ReactRelayContext');
16
17var useLayoutEffect = React.useLayoutEffect,
18 useState = React.useState,
19 useRef = React.useRef,
20 useMemo = React.useMemo;
21
22var _require = require('relay-runtime'),
23 createOperationDescriptor = _require.createOperationDescriptor,
24 deepFreeze = _require.deepFreeze,
25 getRequest = _require.getRequest;
26
27var areEqual = require("fbjs/lib/areEqual");
28
29function useDeepCompare(value) {
30 var latestValue = React.useRef(value);
31
32 if (!areEqual(latestValue.current, value)) {
33 if (process.env.NODE_ENV !== "production") {
34 deepFreeze(value);
35 }
36
37 latestValue.current = value;
38 }
39
40 return latestValue.current;
41}
42
43function ReactRelayLocalQueryRenderer(props) {
44 var environment = props.environment,
45 query = props.query,
46 variables = props.variables,
47 render = props.render;
48 var latestVariables = useDeepCompare(variables);
49 var operation = useMemo(function () {
50 var request = getRequest(query);
51 return createOperationDescriptor(request, latestVariables);
52 }, [query, latestVariables]);
53 var relayContext = useMemo(function () {
54 return {
55 environment: environment
56 };
57 }, [environment]); // Use a ref to prevent rendering twice when data changes
58 // because of props change
59
60 var dataRef = useRef(null);
61
62 var _useState = useState(null),
63 forceUpdate = _useState[1];
64
65 var cleanupFnRef = useRef(null);
66 var snapshot = useMemo(function () {
67 environment.check(operation);
68 var res = environment.lookup(operation.fragment);
69 dataRef.current = res.data; // Run effects here so that the data can be retained
70 // and subscribed before the component commits
71
72 var retainDisposable = environment.retain(operation);
73 var subscribeDisposable = environment.subscribe(res, function (newSnapshot) {
74 dataRef.current = newSnapshot.data;
75 forceUpdate(dataRef.current);
76 });
77 var disposed = false;
78
79 function nextCleanupFn() {
80 if (!disposed) {
81 disposed = true;
82 cleanupFnRef.current = null;
83 retainDisposable.dispose();
84 subscribeDisposable.dispose();
85 }
86 }
87
88 if (cleanupFnRef.current) {
89 cleanupFnRef.current();
90 }
91
92 cleanupFnRef.current = nextCleanupFn;
93 return res;
94 }, [environment, operation]);
95 useLayoutEffect(function () {
96 var cleanupFn = cleanupFnRef.current;
97 return function () {
98 cleanupFn && cleanupFn();
99 };
100 }, [snapshot]);
101 return /*#__PURE__*/React.createElement(ReactRelayContext.Provider, {
102 value: relayContext
103 }, render({
104 props: dataRef.current
105 }));
106}
107
108module.exports = ReactRelayLocalQueryRenderer;
\No newline at end of file