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