import { forwardRef , memo } from "react" ; import { isUsingStaticRendering } from "./staticRendering" ; import { useObserver } from "./useObserver" ; export interface IObserverOptions { readonly forwardRef ? : boolean ; } export function observer < P extends object , TRef = { } > ( baseComponent , options ) ; export function observer < P extends object > ( baseComponent , options ? ) ; export function observer < C extends React . FunctionComponent < any > | React . RefForwardingComponent < any > , Options extends IObserverOptions > ( baseComponent , options ? ) ; export function observer < P extends object , TRef = { } > ( baseComponent , options ? ) { if ( isUsingStaticRendering ( ) ) { return baseComponent ; } const realOptions = { forwardRef : false , ... options } ; const baseComponentName = baseComponent . displayName || baseComponent . name ; const wrappedComponent = ( props , ref ) => { return useObserver ( ( ) => baseComponent ( props , ref ) , baseComponentName ) ; } ; if ( baseComponentName !== "" ) { wrappedComponent . displayName = baseComponentName ; } if ( ( baseComponent as any ) . contextTypes ) { wrappedComponent . contextTypes = ( baseComponent as any ) . contextTypes ; } let memoComponent ; if ( realOptions . forwardRef ) { memoComponent = memo ( forwardRef ( wrappedComponent ) ) ; } else { memoComponent = memo ( wrappedComponent ) ; } copyStaticProperties ( baseComponent , memoComponent ) ; if ( "production" !== process . env . NODE_ENV ) { Object . defineProperty ( memoComponent , "contextTypes" , { set ( ) { throw new Error ( `[mobx-react-lite] \`${ this . displayName || this . type ?. displayName || "Component" }.contextTypes\` must be set before applying \`observer\`.` ) ; } } ) ; } return memoComponent ; } const hoistBlackList = { $$typeof : true , render : true , compare : true , type : true , displayName : true } ; function copyStaticProperties ( base , target ) { Object . keys ( base ) . forEach ( key => { if ( ! hoistBlackList [ key ] ) { Object . defineProperty ( target , key , Object . getOwnPropertyDescriptor ( base , key ) ! ) ; } } ) ; }