1- import { PureComponent , createElement } from 'react' ;
1+ import { PureComponent , createElement , createRef } from 'react' ;
22import { Scope } from './scope' ;
33
44type Props = {
@@ -12,20 +12,76 @@ type State = {
1212 flip : boolean ;
1313} ;
1414
15+ let moduleEntries : any = [ ]
16+
17+ let onMounts : any [ ] = [ ]
18+ let onUpdates : any [ ] = [ ]
19+ let onUnmounts : any [ ] = [ ]
20+
21+ export function setModules ( mods : any ) {
22+ if ( mods === null || typeof mods !== 'object' ) return ;
23+ moduleEntries = Object . entries ( mods )
24+ onMounts = moduleEntries . map ( mod => [ mod [ 0 ] , mod [ 1 ] . componentDidMount ] ) . filter ( mod => mod [ 1 ] )
25+ onUpdates = moduleEntries . map ( mod => [ mod [ 0 ] , mod [ 1 ] . componentDidUpdate ] ) . filter ( mod => mod [ 1 ] )
26+ onUnmounts = moduleEntries . map ( mod => [ mod [ 0 ] , mod [ 1 ] . componentWillUnmount ] ) . filter ( mod => mod [ 1 ] )
27+ }
28+
29+ export function hasModuleProps ( props ) {
30+ return props
31+ ? moduleEntries . some ( ( [ mkey ] ) => props . hasOwnProperty ( mkey ) )
32+ : false
33+ }
34+
35+ function moduleProcessor ( base , current , props ) {
36+ if ( current && base . length ) {
37+ base . forEach ( ( [ key , f ] ) => {
38+ const prop = props [ key ]
39+ if ( prop ) f ( current , prop )
40+ } ) ;
41+ }
42+ }
43+
1544export default class Incorporator extends PureComponent < Props , State > {
45+ private ref : any ;
46+ private selector : string | symbol ;
47+ private unsubscribe : any ;
48+ private element : any ;
49+ private setRef : any ;
50+
1651 constructor ( props : Props ) {
1752 super ( props ) ;
53+ this . element = null
54+
1855 this . state = { flip : false } ;
1956 this . selector = props . targetProps . sel ;
20- }
2157
22- private selector : string | symbol ;
23- private unsubscribe : any ;
58+ const useRef = hasModuleProps ( props . targetProps )
59+ if ( props . targetRef ) {
60+ if ( typeof props . targetRef === 'function' && useRef ) {
61+ this . setRef = element => {
62+ this . element = element ;
63+ props . targetRef ( element ) ;
64+ } ;
65+
66+ this . ref = this . setRef ;
67+ } else {
68+ this . ref = props . targetRef ;
69+ }
70+ } else {
71+ this . ref = useRef ? createRef ( ) : null ;
72+ }
73+ }
2474
2575 public componentDidMount ( ) {
2676 this . unsubscribe = this . props . scope . subscribe ( this . selector , ( ) => {
2777 this . setState ( ( prev : any ) => ( { flip : ! prev . flip } ) ) ;
2878 } ) ;
79+
80+ moduleProcessor ( onMounts , this . element || ( this . ref && this . ref . current ) , this . props . targetProps )
81+ }
82+
83+ public componentDidUpdate ( ) {
84+ moduleProcessor ( onUpdates , this . element || ( this . ref && this . ref . current ) , this . props . targetProps )
2985 }
3086
3187 private incorporateHandlers < P > ( props : P , scope : Scope ) : P {
@@ -38,27 +94,31 @@ export default class Incorporator extends PureComponent<Props, State> {
3894 }
3995
4096 private materializeTargetProps ( ) {
41- const { targetProps, targetRef , scope} = this . props ;
97+ const { targetProps, scope} = this . props ;
4298 let output = { ...targetProps } ;
4399 output = this . incorporateHandlers ( output , scope ) ;
44- if ( targetRef ) {
45- output . ref = targetRef ;
100+ if ( this . ref ) {
101+ output . ref = this . ref ;
46102 }
47103 delete output . sel ;
104+ moduleEntries . forEach ( pair => delete output [ pair [ 0 ] ] )
48105 return output ;
49106 }
50107
51108 public render ( ) {
52109 const { target} = this . props ;
53110 const targetProps = this . materializeTargetProps ( ) ;
111+
54112 if ( targetProps . children ) {
55113 return createElement ( target , targetProps , targetProps . children ) ;
56114 } else {
57115 return createElement ( target , targetProps ) ;
58116 }
59117 }
60118
61- public componentWillUnmount ( ) {
119+ public componentWillUnmount ( ) {
120+ moduleProcessor ( onUnmounts , this . element || ( this . ref && this . ref . current ) , this . props . targetProps )
121+
62122 this . unsubscribe ( ) ;
63123 }
64124}
0 commit comments