import * as React from 'react' ; import { getComponent , isCached , getComponentFromCache } from './map' ; import { mapLoadable } from './bundler' ; type Props < T > = { forwardedRef : React . Ref < T > | null ; } ; type State = { isComponentAvailable : boolean ; } ; const optimized = < T extends { } > ( screenName ) : any => { class OptimizedComponent < T > extends React . PureComponent < Props < T > , State > { private component : React . ElementType | null = null ; private placeholder : React . ElementType | null = mapLoadable [ screenName ] . placeholder ; constructor ( props ) { super ( props ) ; const cached = isCached ( screenName ) ; if ( cached ) { const { component } = getComponentFromCache ( screenName ) ; this . component = component ; } this . state = { isComponentAvailable : cached } ; } public async componentDidMount ( ) { if ( this . component === null ) { const { component } = await getComponent ( screenName ) ; this . component = component ; this . setState ( { isComponentAvailable : true } ) ; } } public render ( ) { const { forwardedRef , ... rest } = this . props ; const BundleComponent = this . component ; const Placeholder = this . placeholder ; const PlaceholderComponent = Placeholder ? < Placeholder /> : Placeholder; return this . state . isComponentAvailable && BundleComponent ? < BundleComponent ref = { forwardedRef } { ... rest } /> : PlaceholderComponent; } } const registerData = mapLoadable [ screenName ] ; if ( registerData . static ) { Object . keys ( registerData . static ) . forEach ( ( key ) => { OptimizedComponent [ key ] = registerData . static [ key ] ; } ) ; } return React . forwardRef ( ( props , ref ) => { return < OptimizedComponent { ... props } forwardedRef = { ref } / > ; } ) ; } ; export default optimized ;