UNPKG

4.55 kBJavaScriptView Raw
1import { forwardRef, memo } from "react";
2import { isUsingStaticRendering } from "./staticRendering";
3import { useObserver } from "./useObserver";
4var warnObserverOptionsDeprecated = true;
5var hasSymbol = typeof Symbol === "function" && Symbol.for;
6// Using react-is had some issues (and operates on elements, not on types), see #608 / #609
7var ReactForwardRefSymbol = hasSymbol
8 ? Symbol.for("react.forward_ref")
9 : typeof forwardRef === "function" && forwardRef(function (props) { return null; })["$$typeof"];
10var ReactMemoSymbol = hasSymbol
11 ? Symbol.for("react.memo")
12 : typeof memo === "function" && memo(function (props) { return null; })["$$typeof"];
13// n.b. base case is not used for actual typings or exported in the typing files
14export function observer(baseComponent,
15// TODO remove in next major
16options) {
17 var _a;
18 if (process.env.NODE_ENV !== "production" && warnObserverOptionsDeprecated && options) {
19 warnObserverOptionsDeprecated = false;
20 console.warn("[mobx-react-lite] `observer(fn, { forwardRef: true })` is deprecated, use `observer(React.forwardRef(fn))`");
21 }
22 if (ReactMemoSymbol && baseComponent["$$typeof"] === ReactMemoSymbol) {
23 throw new Error("[mobx-react-lite] You are trying to use `observer` on a function component wrapped in either another `observer` or `React.memo`. The observer already applies 'React.memo' for you.");
24 }
25 // The working of observer is explained step by step in this talk: https://www.youtube.com/watch?v=cPF4iBedoF0&feature=youtu.be&t=1307
26 if (isUsingStaticRendering()) {
27 return baseComponent;
28 }
29 var useForwardRef = (_a = options === null || options === void 0 ? void 0 : options.forwardRef) !== null && _a !== void 0 ? _a : false;
30 var render = baseComponent;
31 var baseComponentName = baseComponent.displayName || baseComponent.name;
32 // If already wrapped with forwardRef, unwrap,
33 // so we can patch render and apply memo
34 if (ReactForwardRefSymbol && baseComponent["$$typeof"] === ReactForwardRefSymbol) {
35 useForwardRef = true;
36 render = baseComponent["render"];
37 if (typeof render !== "function") {
38 throw new Error("[mobx-react-lite] `render` property of ForwardRef was not a function");
39 }
40 }
41 var observerComponent = function (props, ref) {
42 return useObserver(function () { return render(props, ref); }, baseComponentName);
43 };
44 // Don't set `displayName` for anonymous components,
45 // so the `displayName` can be customized by user, see #3192.
46 if (baseComponentName !== "") {
47 ;
48 observerComponent.displayName = baseComponentName;
49 }
50 // Support legacy context: `contextTypes` must be applied before `memo`
51 if (baseComponent.contextTypes) {
52 ;
53 observerComponent.contextTypes = baseComponent.contextTypes;
54 }
55 if (useForwardRef) {
56 // `forwardRef` must be applied prior `memo`
57 // `forwardRef(observer(cmp))` throws:
58 // "forwardRef requires a render function but received a `memo` component. Instead of forwardRef(memo(...)), use memo(forwardRef(...))"
59 observerComponent = forwardRef(observerComponent);
60 }
61 // memo; we are not interested in deep updates
62 // in props; we assume that if deep objects are changed,
63 // this is in observables, which would have been tracked anyway
64 observerComponent = memo(observerComponent);
65 copyStaticProperties(baseComponent, observerComponent);
66 if ("production" !== process.env.NODE_ENV) {
67 Object.defineProperty(observerComponent, "contextTypes", {
68 set: function () {
69 var _a;
70 throw new Error("[mobx-react-lite] `".concat(this.displayName || ((_a = this.type) === null || _a === void 0 ? void 0 : _a.displayName) || "Component", ".contextTypes` must be set before applying `observer`."));
71 }
72 });
73 }
74 return observerComponent;
75}
76// based on https://github.com/mridgway/hoist-non-react-statics/blob/master/src/index.js
77var hoistBlackList = {
78 $$typeof: true,
79 render: true,
80 compare: true,
81 type: true,
82 // Don't redefine `displayName`,
83 // it's defined as getter-setter pair on `memo` (see #3192).
84 displayName: true
85};
86function copyStaticProperties(base, target) {
87 Object.keys(base).forEach(function (key) {
88 if (!hoistBlackList[key]) {
89 Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(base, key));
90 }
91 });
92}
93//# sourceMappingURL=observer.js.map
\No newline at end of file