mobx-react 7.6.0 → 9.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,52 +9,26 @@ var React = require('react');
9
9
  var React__default = _interopDefault(React);
10
10
  var mobxReactLite = require('mobx-react-lite');
11
11
 
12
- var symbolId = 0;
13
-
14
- function createSymbol(name) {
15
- if (typeof Symbol === "function") {
16
- return Symbol(name);
17
- }
18
-
19
- var symbol = "__$mobx-react " + name + " (" + symbolId + ")";
20
- symbolId++;
21
- return symbol;
22
- }
23
-
24
- var createdSymbols = {};
25
- function newSymbol(name) {
26
- if (!createdSymbols[name]) {
27
- createdSymbols[name] = createSymbol(name);
28
- }
29
-
30
- return createdSymbols[name];
31
- }
32
12
  function shallowEqual(objA, objB) {
33
13
  //From: https://github.com/facebook/fbjs/blob/c69904a511b900266935168223063dd8772dfc40/packages/fbjs/src/core/shallowEqual.js
34
14
  if (is(objA, objB)) {
35
15
  return true;
36
16
  }
37
-
38
17
  if (typeof objA !== "object" || objA === null || typeof objB !== "object" || objB === null) {
39
18
  return false;
40
19
  }
41
-
42
20
  var keysA = Object.keys(objA);
43
21
  var keysB = Object.keys(objB);
44
-
45
22
  if (keysA.length !== keysB.length) {
46
23
  return false;
47
24
  }
48
-
49
25
  for (var i = 0; i < keysA.length; i++) {
50
26
  if (!Object.hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
51
27
  return false;
52
28
  }
53
29
  }
54
-
55
30
  return true;
56
31
  }
57
-
58
32
  function is(x, y) {
59
33
  // From: https://github.com/facebook/fbjs/blob/c69904a511b900266935168223063dd8772dfc40/packages/fbjs/src/core/shallowEqual.js
60
34
  if (x === y) {
@@ -62,9 +36,8 @@ function is(x, y) {
62
36
  } else {
63
37
  return x !== x && y !== y;
64
38
  }
65
- } // based on https://github.com/mridgway/hoist-non-react-statics/blob/master/src/index.js
66
-
67
-
39
+ }
40
+ // based on https://github.com/mridgway/hoist-non-react-statics/blob/master/src/index.js
68
41
  var hoistBlackList = {
69
42
  $$typeof: 1,
70
43
  render: 1,
@@ -89,33 +62,12 @@ function copyStaticProperties(base, target) {
89
62
  }
90
63
  });
91
64
  }
92
- /**
93
- * Helper to set `prop` to `this` as non-enumerable (hidden prop)
94
- * @param target
95
- * @param prop
96
- * @param value
97
- */
98
-
99
- function setHiddenProp(target, prop, value) {
100
- if (!Object.hasOwnProperty.call(target, prop)) {
101
- Object.defineProperty(target, prop, {
102
- enumerable: false,
103
- configurable: true,
104
- writable: true,
105
- value: value
106
- });
107
- } else {
108
- target[prop] = value;
109
- }
110
- }
111
65
  /**
112
66
  * Utilities for patching componentWillUnmount, to make sure @disposeOnUnmount works correctly icm with user defined hooks
113
67
  * and the handler provided by mobx-react
114
68
  */
115
-
116
- var mobxMixins = /*#__PURE__*/newSymbol("patchMixins");
117
- var mobxPatchedDefinition = /*#__PURE__*/newSymbol("patchedDefinition");
118
-
69
+ var mobxMixins = /*#__PURE__*/Symbol("patchMixins");
70
+ var mobxPatchedDefinition = /*#__PURE__*/Symbol("patchedDefinition");
119
71
  function getMixins(target, methodName) {
120
72
  var mixins = target[mobxMixins] = target[mobxMixins] || {};
121
73
  var methodMixins = mixins[methodName] = mixins[methodName] || {};
@@ -123,28 +75,21 @@ function getMixins(target, methodName) {
123
75
  methodMixins.methods = methodMixins.methods || [];
124
76
  return methodMixins;
125
77
  }
126
-
127
78
  function wrapper(realMethod, mixins) {
128
79
  var _this = this;
129
-
130
80
  for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
131
81
  args[_key - 2] = arguments[_key];
132
82
  }
133
-
134
83
  // locks are used to ensure that mixins are invoked only once per invocation, even on recursive calls
135
84
  mixins.locks++;
136
-
137
85
  try {
138
86
  var retVal;
139
-
140
87
  if (realMethod !== undefined && realMethod !== null) {
141
88
  retVal = realMethod.apply(this, args);
142
89
  }
143
-
144
90
  return retVal;
145
91
  } finally {
146
92
  mixins.locks--;
147
-
148
93
  if (mixins.locks === 0) {
149
94
  mixins.methods.forEach(function (mx) {
150
95
  mx.apply(_this, args);
@@ -152,41 +97,31 @@ function wrapper(realMethod, mixins) {
152
97
  }
153
98
  }
154
99
  }
155
-
156
100
  function wrapFunction(realMethod, mixins) {
157
101
  var fn = function fn() {
158
102
  for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
159
103
  args[_key2] = arguments[_key2];
160
104
  }
161
-
162
105
  wrapper.call.apply(wrapper, [this, realMethod, mixins].concat(args));
163
106
  };
164
-
165
107
  return fn;
166
108
  }
167
-
168
109
  function patch(target, methodName, mixinMethod) {
169
110
  var mixins = getMixins(target, methodName);
170
-
171
111
  if (mixins.methods.indexOf(mixinMethod) < 0) {
172
112
  mixins.methods.push(mixinMethod);
173
113
  }
174
-
175
114
  var oldDefinition = Object.getOwnPropertyDescriptor(target, methodName);
176
-
177
115
  if (oldDefinition && oldDefinition[mobxPatchedDefinition]) {
178
116
  // already patched definition, do not repatch
179
117
  return;
180
118
  }
181
-
182
119
  var originalMethod = target[methodName];
183
120
  var newDefinition = createDefinition(target, methodName, oldDefinition ? oldDefinition.enumerable : undefined, mixins, originalMethod);
184
121
  Object.defineProperty(target, methodName, newDefinition);
185
122
  }
186
-
187
123
  function createDefinition(target, methodName, enumerable, mixins, originalMethod) {
188
124
  var _ref;
189
-
190
125
  var wrappedFunc = wrapFunction(originalMethod, mixins);
191
126
  return _ref = {}, _ref[mobxPatchedDefinition] = true, _ref.get = function get() {
192
127
  return wrappedFunc;
@@ -204,247 +139,211 @@ function createDefinition(target, methodName, enumerable, mixins, originalMethod
204
139
  }, _ref.configurable = true, _ref.enumerable = enumerable, _ref;
205
140
  }
206
141
 
207
- var mobxAdminProperty = mobx.$mobx || "$mobx"; // BC
208
-
209
- var mobxObserverProperty = /*#__PURE__*/newSymbol("isMobXReactObserver");
210
- var mobxIsUnmounted = /*#__PURE__*/newSymbol("isUnmounted");
211
- var skipRenderKey = /*#__PURE__*/newSymbol("skipRender");
212
- var isForcingUpdateKey = /*#__PURE__*/newSymbol("isForcingUpdate");
142
+ var administrationSymbol = /*#__PURE__*/Symbol("ObserverAdministration");
143
+ var isMobXReactObserverSymbol = /*#__PURE__*/Symbol("isMobXReactObserver");
144
+ var observablePropDescriptors;
145
+ {
146
+ observablePropDescriptors = {
147
+ props: /*#__PURE__*/createObservablePropDescriptor("props"),
148
+ state: /*#__PURE__*/createObservablePropDescriptor("state"),
149
+ context: /*#__PURE__*/createObservablePropDescriptor("context")
150
+ };
151
+ }
152
+ function getAdministration(component) {
153
+ var _component$administra;
154
+ // We create administration lazily, because we can't patch constructor
155
+ // and the exact moment of initialization partially depends on React internals.
156
+ // At the time of writing this, the first thing invoked is one of the observable getter/setter (state/props/context).
157
+ return (_component$administra = component[administrationSymbol]) != null ? _component$administra : component[administrationSymbol] = {
158
+ reaction: null,
159
+ mounted: false,
160
+ forceUpdate: null,
161
+ name: getDisplayName(component.constructor),
162
+ state: undefined,
163
+ props: undefined,
164
+ context: undefined
165
+ };
166
+ }
213
167
  function makeClassComponentObserver(componentClass) {
214
- var target = componentClass.prototype;
215
-
216
- if (componentClass[mobxObserverProperty]) {
217
- var displayName = getDisplayName(target);
218
- console.warn("The provided component class (" + displayName + ")\n has already been declared as an observer component.");
168
+ var prototype = componentClass.prototype;
169
+ if (componentClass[isMobXReactObserverSymbol]) {
170
+ var displayName = getDisplayName(componentClass);
171
+ throw new Error("The provided component class (" + displayName + ") has already been declared as an observer component.");
219
172
  } else {
220
- componentClass[mobxObserverProperty] = true;
173
+ componentClass[isMobXReactObserverSymbol] = true;
221
174
  }
222
-
223
- if (target.componentWillReact) {
175
+ if (prototype.componentWillReact) {
224
176
  throw new Error("The componentWillReact life-cycle event is no longer supported");
225
177
  }
226
-
227
178
  if (componentClass["__proto__"] !== React.PureComponent) {
228
- if (!target.shouldComponentUpdate) {
229
- target.shouldComponentUpdate = observerSCU;
230
- } else if (target.shouldComponentUpdate !== observerSCU) {
179
+ if (!prototype.shouldComponentUpdate) {
180
+ prototype.shouldComponentUpdate = observerSCU;
181
+ } else if (prototype.shouldComponentUpdate !== observerSCU) {
231
182
  // n.b. unequal check, instead of existence check, as @observer might be on superclass as well
232
183
  throw new Error("It is not allowed to use shouldComponentUpdate in observer based components.");
233
184
  }
234
- } // this.props and this.state are made observable, just to make sure @computed fields that
235
- // are defined inside the component, and which rely on state or props, re-compute if state or props change
236
- // (otherwise the computed wouldn't update and become stale on props change, since props are not observable)
237
- // However, this solution is not without it's own problems: https://github.com/mobxjs/mobx-react/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3Aobservable-props-or-not+
238
-
239
-
240
- makeObservableProp(target, "props");
241
- makeObservableProp(target, "state");
242
-
243
- if (componentClass.contextType) {
244
- makeObservableProp(target, "context");
245
185
  }
246
-
247
- var originalRender = target.render;
248
-
186
+ {
187
+ Object.defineProperties(prototype, observablePropDescriptors);
188
+ }
189
+ var originalRender = prototype.render;
249
190
  if (typeof originalRender !== "function") {
250
- var _displayName = getDisplayName(target);
251
-
191
+ var _displayName = getDisplayName(componentClass);
252
192
  throw new Error("[mobx-react] class component (" + _displayName + ") is missing `render` method." + "\n`observer` requires `render` being a function defined on prototype." + "\n`render = () => {}` or `render = function() {}` is not supported.");
253
193
  }
254
-
255
- target.render = function () {
256
- this.render = mobxReactLite.isUsingStaticRendering() ? originalRender : createReactiveRender.call(this, originalRender);
194
+ prototype.render = function () {
195
+ Object.defineProperty(this, "render", {
196
+ // There is no safe way to replace render, therefore it's forbidden.
197
+ configurable: false,
198
+ writable: false,
199
+ value: mobxReactLite.isUsingStaticRendering() ? originalRender : createReactiveRender.call(this, originalRender)
200
+ });
257
201
  return this.render();
258
202
  };
259
-
260
- patch(target, "componentDidMount", function () {
261
- this[mobxIsUnmounted] = false;
262
-
263
- if (!this.render[mobxAdminProperty]) {
264
- // Reaction is re-created automatically during render, but a component can re-mount and skip render #3395.
265
- // To re-create the reaction and re-subscribe to relevant observables we have to force an update.
266
- React.Component.prototype.forceUpdate.call(this);
203
+ var originalComponentDidMount = prototype.componentDidMount;
204
+ prototype.componentDidMount = function () {
205
+ var _this = this;
206
+ if ( this.componentDidMount !== Object.getPrototypeOf(this).componentDidMount) {
207
+ var _displayName2 = getDisplayName(componentClass);
208
+ throw new Error("[mobx-react] `observer(" + _displayName2 + ").componentDidMount` must be defined on prototype." + "\n`componentDidMount = () => {}` or `componentDidMount = function() {}` is not supported.");
267
209
  }
268
- });
269
- patch(target, "componentWillUnmount", function () {
210
+ // `componentDidMount` may not be called at all. React can abandon the instance after `render`.
211
+ // That's why we use finalization registry to dispose reaction created during render.
212
+ // Happens with `<Suspend>` see #3492
213
+ //
214
+ // `componentDidMount` can be called immediately after `componentWillUnmount` without calling `render` in between.
215
+ // Happens with `<StrictMode>`see #3395.
216
+ //
217
+ // If `componentDidMount` is called, it's guaranteed to run synchronously with render (similary to `useLayoutEffect`).
218
+ // Therefore we don't have to worry about external (observable) state being updated before mount (no state version checking).
219
+ //
220
+ // Things may change: "In the future, React will provide a feature that lets components preserve state between unmounts"
221
+ var admin = getAdministration(this);
222
+ admin.mounted = true;
223
+ // Component instance committed, prevent reaction disposal.
224
+ mobxReactLite._observerFinalizationRegistry.unregister(admin);
225
+ // We don't set forceUpdate before mount because it requires a reference to `this`,
226
+ // therefore `this` could NOT be garbage collected before mount,
227
+ // preventing reaction disposal by FinalizationRegistry and leading to memory leak.
228
+ // As an alternative we could have `admin.instanceRef = new WeakRef(this)`, but lets avoid it if possible.
229
+ admin.forceUpdate = function () {
230
+ return _this.forceUpdate();
231
+ };
232
+ if (!admin.reaction) {
233
+ // 1. Instance was unmounted (reaction disposed) and immediately remounted without running render #3395.
234
+ // 2. Reaction was disposed by finalization registry before mount. Shouldn't ever happen for class components:
235
+ // `componentDidMount` runs synchronously after render, but our registry are deferred (can't run in between).
236
+ // In any case we lost subscriptions to observables, so we have to create new reaction and re-render to resubscribe.
237
+ // The reaction will be created lazily by following render.
238
+ admin.forceUpdate();
239
+ }
240
+ return originalComponentDidMount == null ? void 0 : originalComponentDidMount.apply(this, arguments);
241
+ };
242
+ // TODO@major Overly complicated "patch" is only needed to support the deprecated @disposeOnUnmount
243
+ patch(prototype, "componentWillUnmount", function () {
244
+ var _admin$reaction;
270
245
  if (mobxReactLite.isUsingStaticRendering()) {
271
246
  return;
272
247
  }
273
-
274
- var reaction = this.render[mobxAdminProperty];
275
-
276
- if (reaction) {
277
- reaction.dispose(); // Forces reaction to be re-created on next render
278
-
279
- this.render[mobxAdminProperty] = null;
280
- } else {
281
- // Render may have been hot-swapped and/or overridden by a subclass.
282
- var _displayName2 = getDisplayName(this);
283
-
284
- console.warn("The reactive render of an observer class component (" + _displayName2 + ")\n was overridden after MobX attached. This may result in a memory leak if the\n overridden reactive render was not properly disposed.");
285
- }
286
-
287
- this[mobxIsUnmounted] = true;
248
+ var admin = getAdministration(this);
249
+ (_admin$reaction = admin.reaction) == null ? void 0 : _admin$reaction.dispose();
250
+ admin.reaction = null;
251
+ admin.forceUpdate = null;
252
+ admin.mounted = false;
288
253
  });
289
254
  return componentClass;
290
- } // Generates a friendly name for debugging
291
-
292
- function getDisplayName(comp) {
293
- return comp.displayName || comp.name || comp.constructor && (comp.constructor.displayName || comp.constructor.name) || "<component>";
294
255
  }
295
-
256
+ // Generates a friendly name for debugging
257
+ function getDisplayName(componentClass) {
258
+ return componentClass.displayName || componentClass.name || "<component>";
259
+ }
296
260
  function createReactiveRender(originalRender) {
297
- var _this = this;
298
-
299
- /**
300
- * If props are shallowly modified, react will render anyway,
301
- * so atom.reportChanged() should not result in yet another re-render
302
- */
303
- setHiddenProp(this, skipRenderKey, false);
304
- /**
305
- * forceUpdate will re-assign this.props. We don't want that to cause a loop,
306
- * so detect these changes
307
- */
308
-
309
- setHiddenProp(this, isForcingUpdateKey, false);
310
- var initialName = getDisplayName(this);
311
261
  var boundOriginalRender = originalRender.bind(this);
312
- var isRenderingPending = false;
313
-
314
- var createReaction = function createReaction() {
315
- var reaction = new mobx.Reaction(initialName + ".render()", function () {
316
- if (!isRenderingPending) {
317
- // N.B. Getting here *before mounting* means that a component constructor has side effects (see the relevant test in misc.test.tsx)
318
- // This unidiomatic React usage but React will correctly warn about this so we continue as usual
319
- // See #85 / Pull #44
320
- isRenderingPending = true;
321
-
322
- if (_this[mobxIsUnmounted] !== true) {
323
- var hasError = true;
324
-
325
- try {
326
- setHiddenProp(_this, isForcingUpdateKey, true);
327
-
328
- if (!_this[skipRenderKey]) {
329
- React.Component.prototype.forceUpdate.call(_this);
330
- }
331
-
332
- hasError = false;
333
- } finally {
334
- setHiddenProp(_this, isForcingUpdateKey, false);
335
-
336
- if (hasError) {
337
- reaction.dispose(); // Forces reaction to be re-created on next render
338
-
339
- _this.render[mobxAdminProperty] = null;
340
- }
341
- }
342
- }
343
- }
344
- });
345
- reaction["reactComponent"] = _this;
346
- return reaction;
347
- };
348
-
262
+ var admin = getAdministration(this);
349
263
  function reactiveRender() {
350
- var _reactiveRender$mobxA;
351
-
352
- isRenderingPending = false; // Create reaction lazily to support re-mounting #3395
353
-
354
- var reaction = (_reactiveRender$mobxA = reactiveRender[mobxAdminProperty]) != null ? _reactiveRender$mobxA : reactiveRender[mobxAdminProperty] = createReaction();
355
- var exception = undefined;
356
- var rendering = undefined;
357
- reaction.track(function () {
264
+ if (!admin.reaction) {
265
+ // Create reaction lazily to support re-mounting #3395
266
+ admin.reaction = createReaction(admin);
267
+ if (!admin.mounted) {
268
+ // React can abandon this instance and never call `componentDidMount`/`componentWillUnmount`,
269
+ // we have to make sure reaction will be disposed.
270
+ mobxReactLite._observerFinalizationRegistry.register(this, admin, this);
271
+ }
272
+ }
273
+ var error = undefined;
274
+ var renderResult = undefined;
275
+ admin.reaction.track(function () {
358
276
  try {
359
277
  // TODO@major
360
278
  // Optimization: replace with _allowStateChangesStart/End (not available in mobx@6.0.0)
361
- rendering = mobx._allowStateChanges(false, boundOriginalRender);
279
+ renderResult = mobx._allowStateChanges(false, boundOriginalRender);
362
280
  } catch (e) {
363
- exception = e;
281
+ error = e;
364
282
  }
365
283
  });
366
-
367
- if (exception) {
368
- throw exception;
284
+ if (error) {
285
+ throw error;
369
286
  }
370
-
371
- return rendering;
287
+ return renderResult;
372
288
  }
373
-
374
289
  return reactiveRender;
375
290
  }
376
-
291
+ function createReaction(admin) {
292
+ return new mobx.Reaction(admin.name + ".render()", function () {
293
+ if (!admin.mounted) {
294
+ // This is neccessary to avoid react warning about calling forceUpdate on component that isn't mounted yet.
295
+ // This happens when component is abandoned after render - our reaction is already created and reacts to changes.
296
+ // Due to the synchronous nature of `componenDidMount`, we don't have to worry that component could eventually mount and require update.
297
+ return;
298
+ }
299
+ try {
300
+ admin.forceUpdate == null ? void 0 : admin.forceUpdate();
301
+ } catch (error) {
302
+ var _admin$reaction2;
303
+ (_admin$reaction2 = admin.reaction) == null ? void 0 : _admin$reaction2.dispose();
304
+ admin.reaction = null;
305
+ }
306
+ });
307
+ }
377
308
  function observerSCU(nextProps, nextState) {
378
309
  if (mobxReactLite.isUsingStaticRendering()) {
379
310
  console.warn("[mobx-react] It seems that a re-rendering of a React component is triggered while in static (server-side) mode. Please make sure components are rendered only once server-side.");
380
- } // update on any state changes (as is the default)
381
-
382
-
311
+ }
312
+ // update on any state changes (as is the default)
383
313
  if (this.state !== nextState) {
384
314
  return true;
385
- } // update if props are shallowly not equal, inspired by PureRenderMixin
315
+ }
316
+ // update if props are shallowly not equal, inspired by PureRenderMixin
386
317
  // we could return just 'false' here, and avoid the `skipRender` checks etc
387
318
  // however, it is nicer if lifecycle events are triggered like usually,
388
319
  // so we return true here if props are shallowly modified.
389
-
390
-
391
320
  return !shallowEqual(this.props, nextProps);
392
321
  }
393
-
394
- function makeObservableProp(target, propName) {
395
- var valueHolderKey = newSymbol("reactProp_" + propName + "_valueHolder");
396
- var atomHolderKey = newSymbol("reactProp_" + propName + "_atomHolder");
397
-
398
- function getAtom() {
399
- if (!this[atomHolderKey]) {
400
- setHiddenProp(this, atomHolderKey, mobx.createAtom("reactive " + propName));
401
- }
402
-
403
- return this[atomHolderKey];
404
- }
405
-
406
- Object.defineProperty(target, propName, {
322
+ function createObservablePropDescriptor(key) {
323
+ return {
407
324
  configurable: true,
408
325
  enumerable: true,
409
326
  get: function get() {
410
- var prevReadState = false; // Why this check? BC?
411
- // @ts-expect-error
412
-
413
- if (mobx._allowStateReadsStart && mobx._allowStateReadsEnd) {
414
- prevReadState = mobx._allowStateReadsStart(true);
327
+ var admin = getAdministration(this);
328
+ var derivation = mobx._getGlobalState().trackingDerivation;
329
+ if (derivation && derivation !== admin.reaction) {
330
+ throw new Error("[mobx-react] Cannot read \"" + admin.name + "." + key + "\" in a reactive context, as it isn't observable.\n Please use component lifecycle method to copy the value into a local observable first.\n See https://github.com/mobxjs/mobx/blob/main/packages/mobx-react/README.md#note-on-using-props-and-state-in-derivations");
415
331
  }
416
-
417
- getAtom.call(this).reportObserved(); // Why this check? BC?
418
- // @ts-expect-error
419
-
420
- if (mobx._allowStateReadsStart && mobx._allowStateReadsEnd) {
421
- mobx._allowStateReadsEnd(prevReadState);
422
- }
423
-
424
- return this[valueHolderKey];
332
+ return admin[key];
425
333
  },
426
- set: function set(v) {
427
- if (!this[isForcingUpdateKey] && !shallowEqual(this[valueHolderKey], v)) {
428
- setHiddenProp(this, valueHolderKey, v);
429
- setHiddenProp(this, skipRenderKey, true);
430
- getAtom.call(this).reportChanged();
431
- setHiddenProp(this, skipRenderKey, false);
432
- } else {
433
- setHiddenProp(this, valueHolderKey, v);
434
- }
334
+ set: function set(value) {
335
+ getAdministration(this)[key] = value;
435
336
  }
436
- });
337
+ };
437
338
  }
438
339
 
439
340
  /**
440
341
  * Observer function / decorator
441
342
  */
442
-
443
343
  function observer(component) {
444
344
  if (component["isMobxInjector"] === true) {
445
345
  console.warn("Mobx observer: You are trying to use `observer` on a component that already has `inject`. Please apply `observer` before applying `inject`");
446
346
  }
447
-
448
347
  if (Object.prototype.isPrototypeOf.call(React.Component, component) || Object.prototype.isPrototypeOf.call(React.PureComponent, component)) {
449
348
  // Class component
450
349
  return makeClassComponentObserver(component);
@@ -455,35 +354,29 @@ function observer(component) {
455
354
  }
456
355
 
457
356
  function _extends() {
458
- _extends = Object.assign || function (target) {
357
+ _extends = Object.assign ? Object.assign.bind() : function (target) {
459
358
  for (var i = 1; i < arguments.length; i++) {
460
359
  var source = arguments[i];
461
-
462
360
  for (var key in source) {
463
361
  if (Object.prototype.hasOwnProperty.call(source, key)) {
464
362
  target[key] = source[key];
465
363
  }
466
364
  }
467
365
  }
468
-
469
366
  return target;
470
367
  };
471
-
472
368
  return _extends.apply(this, arguments);
473
369
  }
474
-
475
370
  function _objectWithoutPropertiesLoose(source, excluded) {
476
371
  if (source == null) return {};
477
372
  var target = {};
478
373
  var sourceKeys = Object.keys(source);
479
374
  var key, i;
480
-
481
375
  for (i = 0; i < sourceKeys.length; i++) {
482
376
  key = sourceKeys[i];
483
377
  if (excluded.indexOf(key) >= 0) continue;
484
378
  target[key] = source[key];
485
379
  }
486
-
487
380
  return target;
488
381
  }
489
382
 
@@ -491,21 +384,16 @@ var _excluded = ["children"];
491
384
  var MobXProviderContext = /*#__PURE__*/React__default.createContext({});
492
385
  function Provider(props) {
493
386
  var children = props.children,
494
- stores = _objectWithoutPropertiesLoose(props, _excluded);
495
-
387
+ stores = _objectWithoutPropertiesLoose(props, _excluded);
496
388
  var parentValue = React__default.useContext(MobXProviderContext);
497
389
  var mutableProviderRef = React__default.useRef(_extends({}, parentValue, stores));
498
390
  var value = mutableProviderRef.current;
499
-
500
391
  {
501
392
  var newValue = _extends({}, value, stores); // spread in previous state for the context based stores
502
-
503
-
504
393
  if (!shallowEqual(value, newValue)) {
505
394
  throw new Error("MobX Provider: The set of provided stores has changed. See: https://github.com/mobxjs/mobx-react#the-set-of-provided-stores-has-changed-error.");
506
395
  }
507
396
  }
508
-
509
397
  return React__default.createElement(MobXProviderContext.Provider, {
510
398
  value: value
511
399
  }, children);
@@ -515,38 +403,31 @@ Provider.displayName = "MobXProvider";
515
403
  /**
516
404
  * Store Injection
517
405
  */
518
-
519
406
  function createStoreInjector(grabStoresFn, component, injectNames, makeReactive) {
520
407
  // Support forward refs
521
408
  var Injector = React__default.forwardRef(function (props, ref) {
522
409
  var newProps = _extends({}, props);
523
-
524
410
  var context = React__default.useContext(MobXProviderContext);
525
411
  Object.assign(newProps, grabStoresFn(context || {}, newProps) || {});
526
-
527
412
  if (ref) {
528
413
  newProps.ref = ref;
529
414
  }
530
-
531
415
  return React__default.createElement(component, newProps);
532
416
  });
533
417
  if (makeReactive) Injector = observer(Injector);
534
418
  Injector["isMobxInjector"] = true; // assigned late to suppress observer warning
535
419
  // Static fields from component should be visible on the generated Injector
536
-
537
420
  copyStaticProperties(component, Injector);
538
421
  Injector["wrappedComponent"] = component;
539
422
  Injector.displayName = getInjectName(component, injectNames);
540
423
  return Injector;
541
424
  }
542
-
543
425
  function getInjectName(component, injectNames) {
544
426
  var displayName;
545
427
  var componentName = component.displayName || component.name || component.constructor && component.constructor.name || "Component";
546
428
  if (injectNames) displayName = "inject-with-" + injectNames + "(" + componentName + ")";else displayName = "inject(" + componentName + ")";
547
429
  return displayName;
548
430
  }
549
-
550
431
  function grabStoresByName(storeNames) {
551
432
  return function (baseStores, nextProps) {
552
433
  storeNames.forEach(function (storeName) {
@@ -564,13 +445,10 @@ function grabStoresByName(storeNames) {
564
445
  * or a function that manually maps the available stores from the context to props:
565
446
  * storesToProps(mobxStores, props, context) => newProps
566
447
  */
567
-
568
-
569
448
  function inject() {
570
449
  for (var _len = arguments.length, storeNames = new Array(_len), _key = 0; _key < _len; _key++) {
571
450
  storeNames[_key] = arguments[_key];
572
451
  }
573
-
574
452
  if (typeof arguments[0] === "function") {
575
453
  var grabStoresFn = arguments[0];
576
454
  return function (componentClass) {
@@ -583,14 +461,14 @@ function inject() {
583
461
  }
584
462
  }
585
463
 
586
- var protoStoreKey = /*#__PURE__*/newSymbol("disposeOnUnmountProto");
587
- var instStoreKey = /*#__PURE__*/newSymbol("disposeOnUnmountInst");
588
-
464
+ var reactMajorVersion = /*#__PURE__*/Number.parseInt( /*#__PURE__*/React__default.version.split(".")[0]);
465
+ var warnedAboutDisposeOnUnmountDeprecated = false;
466
+ var protoStoreKey = /*#__PURE__*/Symbol("disposeOnUnmountProto");
467
+ var instStoreKey = /*#__PURE__*/Symbol("disposeOnUnmountInst");
589
468
  function runDisposersOnWillUnmount() {
590
469
  var _this = this;
591
470
  [].concat(this[protoStoreKey] || [], this[instStoreKey] || []).forEach(function (propKeyOrFunction) {
592
471
  var prop = typeof propKeyOrFunction === "string" ? _this[propKeyOrFunction] : propKeyOrFunction;
593
-
594
472
  if (prop !== undefined && prop !== null) {
595
473
  if (Array.isArray(prop)) prop.map(function (f) {
596
474
  return f();
@@ -598,62 +476,67 @@ function runDisposersOnWillUnmount() {
598
476
  }
599
477
  });
600
478
  }
601
-
479
+ /**
480
+ * @deprecated `disposeOnUnmount` is not compatible with React 18 and higher.
481
+ */
602
482
  function disposeOnUnmount(target, propertyKeyOrFunction) {
603
483
  if (Array.isArray(propertyKeyOrFunction)) {
604
484
  return propertyKeyOrFunction.map(function (fn) {
605
485
  return disposeOnUnmount(target, fn);
606
486
  });
607
487
  }
608
-
488
+ if (!warnedAboutDisposeOnUnmountDeprecated) {
489
+ if (reactMajorVersion >= 18) {
490
+ console.error("[mobx-react] disposeOnUnmount is not compatible with React 18 and higher. Don't use it.");
491
+ } else {
492
+ console.warn("[mobx-react] disposeOnUnmount is deprecated. It won't work correctly with React 18 and higher.");
493
+ }
494
+ warnedAboutDisposeOnUnmountDeprecated = true;
495
+ }
609
496
  var c = Object.getPrototypeOf(target).constructor;
610
- var c2 = Object.getPrototypeOf(target.constructor); // Special case for react-hot-loader
611
-
497
+ var c2 = Object.getPrototypeOf(target.constructor);
498
+ // Special case for react-hot-loader
612
499
  var c3 = Object.getPrototypeOf(Object.getPrototypeOf(target));
613
-
614
500
  if (!(c === React__default.Component || c === React__default.PureComponent || c2 === React__default.Component || c2 === React__default.PureComponent || c3 === React__default.Component || c3 === React__default.PureComponent)) {
615
501
  throw new Error("[mobx-react] disposeOnUnmount only supports direct subclasses of React.Component or React.PureComponent.");
616
502
  }
617
-
618
503
  if (typeof propertyKeyOrFunction !== "string" && typeof propertyKeyOrFunction !== "function" && !Array.isArray(propertyKeyOrFunction)) {
619
504
  throw new Error("[mobx-react] disposeOnUnmount only works if the parameter is either a property key or a function.");
620
- } // decorator's target is the prototype, so it doesn't have any instance properties like props
621
-
622
-
623
- var isDecorator = typeof propertyKeyOrFunction === "string"; // add property key / function we want run (disposed) to the store
624
-
505
+ }
506
+ // decorator's target is the prototype, so it doesn't have any instance properties like props
507
+ var isDecorator = typeof propertyKeyOrFunction === "string";
508
+ // add property key / function we want run (disposed) to the store
625
509
  var componentWasAlreadyModified = !!target[protoStoreKey] || !!target[instStoreKey];
626
- var store = isDecorator ? // decorators are added to the prototype store
627
- target[protoStoreKey] || (target[protoStoreKey] = []) : // functions are added to the instance store
510
+ var store = isDecorator ?
511
+ // decorators are added to the prototype store
512
+ target[protoStoreKey] || (target[protoStoreKey] = []) :
513
+ // functions are added to the instance store
628
514
  target[instStoreKey] || (target[instStoreKey] = []);
629
- store.push(propertyKeyOrFunction); // tweak the component class componentWillUnmount if not done already
630
-
515
+ store.push(propertyKeyOrFunction);
516
+ // tweak the component class componentWillUnmount if not done already
631
517
  if (!componentWasAlreadyModified) {
632
518
  patch(target, "componentWillUnmount", runDisposersOnWillUnmount);
633
- } // return the disposer as is if invoked as a non decorator
634
-
635
-
519
+ }
520
+ // return the disposer as is if invoked as a non decorator
636
521
  if (typeof propertyKeyOrFunction !== "string") {
637
522
  return propertyKeyOrFunction;
638
523
  }
639
524
  }
640
525
 
526
+ // Copied from React.PropTypes
641
527
  function createChainableTypeChecker(validator) {
642
528
  function checkType(isRequired, props, propName, componentName, location, propFullName) {
643
529
  for (var _len = arguments.length, rest = new Array(_len > 6 ? _len - 6 : 0), _key = 6; _key < _len; _key++) {
644
530
  rest[_key - 6] = arguments[_key];
645
531
  }
646
-
647
532
  return mobx.untracked(function () {
648
533
  componentName = componentName || "<<anonymous>>";
649
534
  propFullName = propFullName || propName;
650
-
651
535
  if (props[propName] == null) {
652
536
  if (isRequired) {
653
537
  var actual = props[propName] === null ? "null" : "undefined";
654
538
  return new Error("The " + location + " `" + propFullName + "` is marked as required " + "in `" + componentName + "`, but its value is `" + actual + "`.");
655
539
  }
656
-
657
540
  return null;
658
541
  } else {
659
542
  // @ts-ignore rest arg is necessary for some React internals - fails tests otherwise
@@ -661,60 +544,48 @@ function createChainableTypeChecker(validator) {
661
544
  }
662
545
  });
663
546
  }
664
-
665
- var chainedCheckType = checkType.bind(null, false); // Add isRequired to satisfy Requirable
666
-
547
+ var chainedCheckType = checkType.bind(null, false);
548
+ // Add isRequired to satisfy Requirable
667
549
  chainedCheckType.isRequired = checkType.bind(null, true);
668
550
  return chainedCheckType;
669
- } // Copied from React.PropTypes
670
-
671
-
551
+ }
552
+ // Copied from React.PropTypes
672
553
  function isSymbol(propType, propValue) {
673
554
  // Native Symbol.
674
555
  if (propType === "symbol") {
675
556
  return true;
676
- } // 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol'
677
-
678
-
557
+ }
558
+ // 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol'
679
559
  if (propValue["@@toStringTag"] === "Symbol") {
680
560
  return true;
681
- } // Fallback for non-spec compliant Symbols which are polyfilled.
682
-
683
-
561
+ }
562
+ // Fallback for non-spec compliant Symbols which are polyfilled.
684
563
  if (typeof Symbol === "function" && propValue instanceof Symbol) {
685
564
  return true;
686
565
  }
687
-
688
566
  return false;
689
- } // Copied from React.PropTypes
690
-
691
-
567
+ }
568
+ // Copied from React.PropTypes
692
569
  function getPropType(propValue) {
693
570
  var propType = typeof propValue;
694
-
695
571
  if (Array.isArray(propValue)) {
696
572
  return "array";
697
573
  }
698
-
699
574
  if (propValue instanceof RegExp) {
700
575
  // Old webkits (at least until Android 4.0) return 'function' rather than
701
576
  // 'object' for typeof a RegExp. We'll normalize this here so that /bla/
702
577
  // passes PropTypes.object.
703
578
  return "object";
704
579
  }
705
-
706
580
  if (isSymbol(propType, propValue)) {
707
581
  return "symbol";
708
582
  }
709
-
710
583
  return propType;
711
- } // This handles more types than `getPropType`. Only used for error messages.
584
+ }
585
+ // This handles more types than `getPropType`. Only used for error messages.
712
586
  // Copied from React.PropTypes
713
-
714
-
715
587
  function getPreciseType(propValue) {
716
588
  var propType = getPropType(propValue);
717
-
718
589
  if (propType === "object") {
719
590
  if (propValue instanceof Date) {
720
591
  return "date";
@@ -722,55 +593,43 @@ function getPreciseType(propValue) {
722
593
  return "regexp";
723
594
  }
724
595
  }
725
-
726
596
  return propType;
727
597
  }
728
-
729
598
  function createObservableTypeCheckerCreator(allowNativeType, mobxType) {
730
599
  return createChainableTypeChecker(function (props, propName, componentName, location, propFullName) {
731
600
  return mobx.untracked(function () {
732
601
  if (allowNativeType) {
733
602
  if (getPropType(props[propName]) === mobxType.toLowerCase()) return null;
734
603
  }
735
-
736
604
  var mobxChecker;
737
-
738
605
  switch (mobxType) {
739
606
  case "Array":
740
607
  mobxChecker = mobx.isObservableArray;
741
608
  break;
742
-
743
609
  case "Object":
744
610
  mobxChecker = mobx.isObservableObject;
745
611
  break;
746
-
747
612
  case "Map":
748
613
  mobxChecker = mobx.isObservableMap;
749
614
  break;
750
-
751
615
  default:
752
616
  throw new Error("Unexpected mobxType: " + mobxType);
753
617
  }
754
-
755
618
  var propValue = props[propName];
756
-
757
619
  if (!mobxChecker(propValue)) {
758
620
  var preciseType = getPreciseType(propValue);
759
621
  var nativeTypeExpectationMessage = allowNativeType ? " or javascript `" + mobxType.toLowerCase() + "`" : "";
760
622
  return new Error("Invalid prop `" + propFullName + "` of type `" + preciseType + "` supplied to" + " `" + componentName + "`, expected `mobx.Observable" + mobxType + "`" + nativeTypeExpectationMessage + ".");
761
623
  }
762
-
763
624
  return null;
764
625
  });
765
626
  });
766
627
  }
767
-
768
628
  function createObservableArrayOfTypeChecker(allowNativeType, typeChecker) {
769
629
  return createChainableTypeChecker(function (props, propName, componentName, location, propFullName) {
770
630
  for (var _len2 = arguments.length, rest = new Array(_len2 > 5 ? _len2 - 5 : 0), _key2 = 5; _key2 < _len2; _key2++) {
771
631
  rest[_key2 - 5] = arguments[_key2];
772
632
  }
773
-
774
633
  return mobx.untracked(function () {
775
634
  if (typeof typeChecker !== "function") {
776
635
  return new Error("Property `" + propFullName + "` of component `" + componentName + "` has " + "invalid PropType notation.");
@@ -778,18 +637,15 @@ function createObservableArrayOfTypeChecker(allowNativeType, typeChecker) {
778
637
  var error = createObservableTypeCheckerCreator(allowNativeType, "Array")(props, propName, componentName, location, propFullName);
779
638
  if (error instanceof Error) return error;
780
639
  var propValue = props[propName];
781
-
782
640
  for (var i = 0; i < propValue.length; i++) {
783
641
  error = typeChecker.apply(void 0, [propValue, i, componentName, location, propFullName + "[" + i + "]"].concat(rest));
784
642
  if (error instanceof Error) return error;
785
643
  }
786
-
787
644
  return null;
788
645
  }
789
646
  });
790
647
  });
791
648
  }
792
-
793
649
  var observableArray = /*#__PURE__*/createObservableTypeCheckerCreator(false, "Array");
794
650
  var observableArrayOf = /*#__PURE__*/createObservableArrayOfTypeChecker.bind(null, false);
795
651
  var observableMap = /*#__PURE__*/createObservableTypeCheckerCreator(false, "Map");
@@ -807,8 +663,12 @@ var PropTypes = {
807
663
  objectOrObservableObject: objectOrObservableObject
808
664
  };
809
665
 
810
- if (!React.Component) throw new Error("mobx-react requires React to be available");
811
- if (!mobx.observable) throw new Error("mobx-react requires mobx to be available");
666
+ if (!React.Component) {
667
+ throw new Error("mobx-react requires React to be available");
668
+ }
669
+ if (!mobx.observable) {
670
+ throw new Error("mobx-react requires mobx to be available");
671
+ }
812
672
 
813
673
  Object.defineProperty(exports, 'Observer', {
814
674
  enumerable: true,