@@ -17,14 +17,21 @@ const defaultMergeProps = (stateProps, dispatchProps, parentProps) => ({
17
17
function isFunction ( fn ) {
18
18
return typeof fn === 'function'
19
19
}
20
- function isFactory ( fn ) {
21
- return isFunction ( fn ) && fn . length === 0 && isFunction ( fn ( ) )
22
- }
23
20
24
21
function getDisplayName ( WrappedComponent ) {
25
22
return WrappedComponent . displayName || WrappedComponent . name || 'Component'
26
23
}
27
24
25
+ function checkStateShape ( stateProps , dispatch ) {
26
+ invariant (
27
+ isPlainObject ( stateProps ) ,
28
+ '`%sToProps` must return an object. Instead received %s.' ,
29
+ dispatch ? 'mapDispatch' : 'mapState' ,
30
+ stateProps
31
+ )
32
+ return stateProps
33
+ }
34
+
28
35
// Helps track hot reloading.
29
36
let nextVersion = 0
30
37
@@ -35,9 +42,6 @@ export default function connect(mapStateToProps, mapDispatchToProps, mergeProps,
35
42
wrapActionCreators ( mapDispatchToProps ) :
36
43
mapDispatchToProps || defaultMapDispatchToProps
37
44
38
- const mapStateFactory = isFactory ( mapState ) ? mapState : ( ( ) => mapState )
39
- const mapDispatchFactory = isFactory ( mapDispatch ) ? mapDispatch : ( ( ) => mapDispatch )
40
-
41
45
const finalMergeProps = mergeProps || defaultMergeProps
42
46
const { pure = true , withRef = false } = options
43
47
@@ -62,45 +66,48 @@ export default function connect(mapStateToProps, mapDispatchToProps, mergeProps,
62
66
`or explicitly pass "store" as a prop to "${ this . constructor . displayName } ".`
63
67
)
64
68
65
- this . configure ( )
66
69
const storeState = this . store . getState ( )
67
70
this . state = { storeState }
68
71
this . clearCache ( )
69
72
}
70
73
71
- configure ( ) {
72
- this . finalMapStateToProps = mapStateFactory ( )
73
- this . finalMapDispatchToProps = mapDispatchFactory ( )
74
- this . doStatePropsDependOnOwnProps = this . finalMapStateToProps . length !== 1
75
- this . doDispatchPropsDependOnOwnProps = this . finalMapDispatchToProps . length !== 1
76
- }
77
-
78
74
computeStateProps ( store , props ) {
75
+ if ( ! this . finalMapStateToProps ) {
76
+ return this . configureFinalMapState ( store , props )
77
+ }
79
78
const state = store . getState ( )
80
79
const stateProps = this . doStatePropsDependOnOwnProps ?
81
80
this . finalMapStateToProps ( state , props ) :
82
81
this . finalMapStateToProps ( state )
83
82
84
- invariant (
85
- isPlainObject ( stateProps ) ,
86
- '`mapStateToProps` must return an object. Instead received %s.' ,
87
- stateProps
88
- )
89
- return stateProps
83
+ return checkStateShape ( stateProps )
84
+ }
85
+
86
+ configureFinalMapState ( store , props ) {
87
+ const mappedState = mapState ( store . getState ( ) , props )
88
+ const isFactory = isFunction ( mappedState )
89
+ this . finalMapStateToProps = isFactory ? mappedState : mapState
90
+ this . doStatePropsDependOnOwnProps = this . finalMapStateToProps . length !== 1
91
+ return isFactory ? this . computeStateProps ( store , props ) : checkStateShape ( mappedState )
90
92
}
91
93
92
94
computeDispatchProps ( store , props ) {
95
+ if ( ! this . finalMapDispatchToProps ) {
96
+ return this . configureFinalMapDispatch ( store , props )
97
+ }
93
98
const { dispatch } = store
94
99
const dispatchProps = this . doDispatchPropsDependOnOwnProps ?
95
100
this . finalMapDispatchToProps ( dispatch , props ) :
96
101
this . finalMapDispatchToProps ( dispatch )
102
+ return checkStateShape ( dispatchProps , true )
103
+ }
97
104
98
- invariant (
99
- isPlainObject ( dispatchProps ) ,
100
- '`mapDispatchToProps` must return an object. Instead received %s.' ,
101
- dispatchProps
102
- )
103
- return dispatchProps
105
+ configureFinalMapDispatch ( store , props ) {
106
+ const mappedDispatch = mapDispatch ( store . dispatch , props )
107
+ const isFactory = isFunction ( mappedDispatch )
108
+ this . finalMapDispatchToProps = isFactory ? mappedDispatch : mapDispatch
109
+ this . doDispatchPropsDependOnOwnProps = this . finalMapDispatchToProps . length !== 1
110
+ return isFactory ? this . computeDispatchProps ( store , props ) : checkStateShape ( mappedDispatch , true )
104
111
}
105
112
106
113
computeMergedProps ( stateProps , dispatchProps , parentProps ) {
@@ -181,6 +188,8 @@ export default function connect(mapStateToProps, mapDispatchToProps, mergeProps,
181
188
this . haveOwnPropsChanged = true
182
189
this . hasStoreStateChanged = true
183
190
this . renderedElement = null
191
+ this . finalMapDispatchToProps = null
192
+ this . finalMapStateToProps = null
184
193
}
185
194
186
195
handleChange ( ) {
@@ -282,7 +291,6 @@ export default function connect(mapStateToProps, mapDispatchToProps, mergeProps,
282
291
283
292
// We are hot reloading!
284
293
this . version = version
285
- this . configure ( )
286
294
this . trySubscribe ( )
287
295
this . clearCache ( )
288
296
}
0 commit comments