UNPKG

6.37 kBJavaScriptView Raw
1/**
2 * @license React
3 * create-subscription.development.js
4 *
5 * Copyright (c) Facebook, Inc. and its affiliates.
6 *
7 * This source code is licensed under the MIT license found in the
8 * LICENSE file in the root directory of this source tree.
9 */
10
11'use strict';
12
13if (process.env.NODE_ENV !== "production") {
14 (function() {
15
16 'use strict';
17
18/* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
19if (
20 typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' &&
21 typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart ===
22 'function'
23) {
24 __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error());
25}
26 var React = require('react');
27
28function _inheritsLoose(subClass, superClass) {
29 subClass.prototype = Object.create(superClass.prototype);
30 subClass.prototype.constructor = subClass;
31 subClass.__proto__ = superClass;
32}
33
34var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
35
36function error(format) {
37 {
38 {
39 for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
40 args[_key2 - 1] = arguments[_key2];
41 }
42
43 printWarning('error', format, args);
44 }
45 }
46}
47
48function printWarning(level, format, args) {
49 // When changing this logic, you might want to also
50 // update consoleWithStackDev.www.js as well.
51 {
52 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
53 var stack = ReactDebugCurrentFrame.getStackAddendum();
54
55 if (stack !== '') {
56 format += '%s';
57 args = args.concat([stack]);
58 } // eslint-disable-next-line react-internal/safe-string-coercion
59
60
61 var argsWithFormat = args.map(function (item) {
62 return String(item);
63 }); // Careful: RN currently depends on this prefix
64
65 argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it
66 // breaks IE9: https://github.com/facebook/react/issues/13610
67 // eslint-disable-next-line react-internal/no-production-logging
68
69 Function.prototype.apply.call(console[level], console, argsWithFormat);
70 }
71}
72
73function createSubscription(config) {
74 var getCurrentValue = config.getCurrentValue,
75 _subscribe = config.subscribe;
76
77 {
78 if (typeof getCurrentValue !== 'function') {
79 error('Subscription must specify a getCurrentValue function');
80 }
81
82 if (typeof _subscribe !== 'function') {
83 error('Subscription must specify a subscribe function');
84 }
85 }
86
87 // Reference: https://gist.github.com/bvaughn/d569177d70b50b58bff69c3c4a5353f3
88 var Subscription = /*#__PURE__*/function (_React$Component) {
89 _inheritsLoose(Subscription, _React$Component);
90
91 function Subscription() {
92 var _this;
93
94 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
95 args[_key] = arguments[_key];
96 }
97
98 _this = _React$Component.call.apply(_React$Component, [this].concat(args)) || this;
99 _this.state = {
100 source: _this.props.source,
101 value: _this.props.source != null ? getCurrentValue(_this.props.source) : undefined
102 };
103 _this._hasUnmounted = false;
104 _this._unsubscribe = null;
105 return _this;
106 }
107
108 Subscription.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps, prevState) {
109 if (nextProps.source !== prevState.source) {
110 return {
111 source: nextProps.source,
112 value: nextProps.source != null ? getCurrentValue(nextProps.source) : undefined
113 };
114 }
115
116 return null;
117 };
118
119 var _proto = Subscription.prototype;
120
121 _proto.componentDidMount = function componentDidMount() {
122 this.subscribe();
123 };
124
125 _proto.componentDidUpdate = function componentDidUpdate(prevProps, prevState) {
126 if (this.state.source !== prevState.source) {
127 this.unsubscribe();
128 this.subscribe();
129 }
130 };
131
132 _proto.componentWillUnmount = function componentWillUnmount() {
133 this.unsubscribe(); // Track mounted to avoid calling setState after unmounting
134 // For source like Promises that can't be unsubscribed from.
135
136 this._hasUnmounted = true;
137 };
138
139 _proto.render = function render() {
140 return this.props.children(this.state.value);
141 };
142
143 _proto.subscribe = function subscribe() {
144 var _this2 = this;
145
146 var source = this.state.source;
147
148 if (source != null) {
149 var _callback = function (value) {
150 if (_this2._hasUnmounted) {
151 return;
152 }
153
154 _this2.setState(function (state) {
155 // If the value is the same, skip the unnecessary state update.
156 if (value === state.value) {
157 return null;
158 } // If this event belongs to an old or uncommitted data source, ignore it.
159
160
161 if (source !== state.source) {
162 return null;
163 }
164
165 return {
166 value: value
167 };
168 });
169 }; // Store the unsubscribe method for later (in case the subscribable prop changes).
170
171
172 var unsubscribe = _subscribe(source, _callback);
173
174 if (typeof unsubscribe !== 'function') {
175 throw new Error('A subscription must return an unsubscribe function.');
176 } // It's safe to store unsubscribe on the instance because
177 // We only read or write that property during the "commit" phase.
178
179
180 this._unsubscribe = unsubscribe; // External values could change between render and mount,
181 // In some cases it may be important to handle this case.
182
183 var _value = getCurrentValue(this.props.source);
184
185 if (_value !== this.state.value) {
186 this.setState({
187 value: _value
188 });
189 }
190 }
191 };
192
193 _proto.unsubscribe = function unsubscribe() {
194 if (typeof this._unsubscribe === 'function') {
195 this._unsubscribe();
196 }
197
198 this._unsubscribe = null;
199 };
200
201 return Subscription;
202 }(React.Component);
203
204 return Subscription;
205}
206
207exports.createSubscription = createSubscription;
208 /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
209if (
210 typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' &&
211 typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop ===
212 'function'
213) {
214 __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(new Error());
215}
216
217 })();
218}