1 | import * as React from "react"
|
2 | import { observer as observerLite, Observer } from "mobx-react-lite"
|
3 |
|
4 | import { makeClassComponentObserver } from "./observerClass"
|
5 | import { IReactComponent } from "./types/IReactComponent"
|
6 |
|
7 | const hasSymbol = typeof Symbol === "function" && Symbol.for
|
8 |
|
9 |
|
10 | const ReactForwardRefSymbol = hasSymbol
|
11 | ? Symbol.for("react.forward_ref")
|
12 | : typeof React.forwardRef === "function" && React.forwardRef((props: any) => null)["$$typeof"]
|
13 |
|
14 | const ReactMemoSymbol = hasSymbol
|
15 | ? Symbol.for("react.memo")
|
16 | : typeof React.memo === "function" && React.memo((props: any) => null)["$$typeof"]
|
17 |
|
18 |
|
19 |
|
20 |
|
21 | export function observer<T extends IReactComponent>(component: T): T {
|
22 | if (component["isMobxInjector"] === true) {
|
23 | console.warn(
|
24 | "Mobx observer: You are trying to use 'observer' on a component that already has 'inject'. Please apply 'observer' before applying 'inject'"
|
25 | )
|
26 | }
|
27 |
|
28 | if (ReactMemoSymbol && component["$$typeof"] === ReactMemoSymbol) {
|
29 | throw new Error(
|
30 | "Mobx observer: 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."
|
31 | )
|
32 | }
|
33 |
|
34 |
|
35 |
|
36 |
|
37 | if (ReactForwardRefSymbol && component["$$typeof"] === ReactForwardRefSymbol) {
|
38 | const baseRender = component["render"]
|
39 | if (typeof baseRender !== "function")
|
40 | throw new Error("render property of ForwardRef was not a function")
|
41 | return React.forwardRef(function ObserverForwardRef() {
|
42 | const args = arguments
|
43 | return <Observer>{() => baseRender.apply(undefined, args)}</Observer>
|
44 | }) as T
|
45 | }
|
46 |
|
47 |
|
48 | if (
|
49 | typeof component === "function" &&
|
50 | (!component.prototype || !component.prototype.render) &&
|
51 | !component["isReactClass"] &&
|
52 | !Object.prototype.isPrototypeOf.call(React.Component, component)
|
53 | ) {
|
54 | return observerLite(component as React.StatelessComponent<any>) as T
|
55 | }
|
56 |
|
57 | return makeClassComponentObserver(component as React.ComponentClass<any, any>) as T
|
58 | }
|