1
- import createReactClass from 'create-react-class' ;
2
-
3
1
// See https://github.com/alibaba/rax/blob/master/packages/rax-create-class/src/index.js
4
2
// Imported by 'rax-compat/createReactClass'
5
- export default createReactClass ;
3
+ import type { ComponentSpec , ClassicComponentClass } from 'react' ;
4
+ import { Component } from 'react' ;
5
+
6
+ const AUTOBIND_BLACKLIST = {
7
+ render : 1 ,
8
+ shouldComponentUpdate : 1 ,
9
+ componentWillReceiveProps : 1 ,
10
+ componentWillUpdate : 1 ,
11
+ componentDidUpdate : 1 ,
12
+ componentWillMount : 1 ,
13
+ componentDidMount : 1 ,
14
+ componentWillUnmount : 1 ,
15
+ componentDidUnmount : 1 ,
16
+ } ;
17
+
18
+ function collateMixins ( mixins : any ) {
19
+ let keyed : Record < string , any > = { } ;
20
+
21
+ for ( let i = 0 ; i < mixins . length ; i ++ ) {
22
+ let mixin = mixins [ i ] ;
23
+ if ( mixin . mixins ) {
24
+ applyMixins ( mixin , collateMixins ( mixin . mixins ) ) ;
25
+ }
26
+
27
+ for ( let key in mixin ) {
28
+ if ( mixin . hasOwnProperty ( key ) && key !== 'mixins' ) {
29
+ ( keyed [ key ] || ( keyed [ key ] = [ ] ) ) . push ( mixin [ key ] ) ;
30
+ }
31
+ }
32
+ }
33
+
34
+ return keyed ;
35
+ }
36
+
37
+ function flattenHooks ( key : string , hooks : Array < any > ) {
38
+ let hookType = typeof hooks [ 0 ] ;
39
+ // Consider "null" value.
40
+ if ( hooks [ 0 ] && hookType === 'object' ) {
41
+ // Merge objects in hooks
42
+ hooks . unshift ( { } ) ;
43
+ return Object . assign . apply ( null , hooks ) ;
44
+ } else if ( hookType === 'function' && ( key === 'getInitialState' || key === 'getDefaultProps' || key === 'getChildContext' ) ) {
45
+ return function ( ) {
46
+ let ret ;
47
+ for ( let i = 0 ; i < hooks . length ; i ++ ) {
48
+ // @ts -ignore
49
+ let r = hooks [ i ] . apply ( this , arguments ) ;
50
+ if ( r ) {
51
+ if ( ! ret ) ret = { } ;
52
+ Object . assign ( ret , r ) ;
53
+ }
54
+ }
55
+ return ret ;
56
+ } ;
57
+ } else {
58
+ return hooks [ 0 ] ;
59
+ }
60
+ }
61
+ function applyMixins ( proto : any , mixins : Record < string , any > ) {
62
+ for ( let key in mixins ) {
63
+ // eslint-disable-next-line no-prototype-builtins
64
+ if ( mixins . hasOwnProperty ( key ) ) {
65
+ proto [ key ] = flattenHooks ( key , mixins [ key ] . concat ( proto [ key ] || [ ] ) ) ;
66
+ }
67
+ }
68
+ }
69
+
70
+ function createReactClass < P , S = { } > ( spec : ComponentSpec < P , S > ) : ClassicComponentClass < P > {
71
+ class ReactClass extends Component < P , S > {
72
+ constructor ( props : P , context : any ) {
73
+ super ( props , context ) ;
74
+
75
+ for ( let methodName in this ) {
76
+ let method = this [ methodName ] ;
77
+ // @ts -ignore
78
+ if ( typeof method === 'function' && ! AUTOBIND_BLACKLIST [ methodName ] ) {
79
+ this [ methodName ] = method . bind ( this ) ;
80
+ }
81
+ }
82
+
83
+ if ( spec . getInitialState ) {
84
+ this . state = spec . getInitialState . call ( this ) ;
85
+ }
86
+ }
87
+ }
88
+
89
+ if ( spec . mixins ) {
90
+ applyMixins ( spec , collateMixins ( spec . mixins ) ) ;
91
+ }
92
+
93
+ // Not to pass contextTypes to prototype.
94
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
95
+ const { propTypes, contextTypes, ...others } = spec ;
96
+ Object . assign ( ReactClass . prototype , others ) ;
97
+
98
+ if ( spec . statics ) {
99
+ Object . assign ( ReactClass , spec . statics ) ;
100
+ }
101
+
102
+ if ( spec . propTypes ) {
103
+ // @ts -ignore
104
+ ReactClass . propTypes = spec . propTypes ;
105
+ }
106
+
107
+ if ( spec . getDefaultProps ) {
108
+ // @ts -ignore
109
+ ReactClass . defaultProps = spec . getDefaultProps ( ) ;
110
+ }
111
+
112
+ if ( spec . contextTypes ) {
113
+ // @ts -ignore
114
+ ReactClass . contextTypes = spec . contextTypes ;
115
+ }
116
+
117
+ if ( spec . childContextTypes ) {
118
+ // @ts -ignore
119
+ ReactClass . childContextTypes = spec . childContextTypes ;
120
+ }
121
+
122
+ if ( spec . displayName ) {
123
+ // @ts -ignore
124
+ ReactClass . displayName = spec . displayName ;
125
+ }
126
+
127
+ return ReactClass as ClassicComponentClass < P > ;
128
+ }
129
+ export default createReactClass ;
0 commit comments