@@ -24,7 +24,6 @@ function tryCatch(fn, ctx) {
24
24
try {
25
25
return fn . apply ( ctx )
26
26
} catch ( e ) {
27
- console . error ( e )
28
27
errorObject . value = e
29
28
return errorObject
30
29
}
@@ -48,7 +47,6 @@ export default function connect(mapStateToProps, mapDispatchToProps, mergeProps,
48
47
49
48
const finalMergeProps = mergeProps || defaultMergeProps
50
49
const { pure = true , withRef = false } = options
51
- const checkMergedEquals = pure && finalMergeProps !== defaultMergeProps
52
50
53
51
// Helps track hot reloading.
54
52
const version = nextVersion ++
@@ -75,22 +73,12 @@ export default function connect(mapStateToProps, mapDispatchToProps, mergeProps,
75
73
76
74
class Connect extends Component {
77
75
78
- shouldComponentUpdate ( nextProps , nextState ) {
79
-
76
+ shouldComponentUpdate ( ) {
80
77
if ( this . skipNextRender ) {
81
- this . skipNextRender = false ;
82
- return false ;
78
+ this . skipNextRender = false
79
+ return false
83
80
}
84
-
85
- /*
86
- console.log("shouldComponentUpdate",!pure || nextState.mergedPropsUpdated)
87
- console.log("shouldComponentUpdate",!pure || nextState.mergedPropsUpdated)
88
- console.log("shouldComponentUpdate",nextState)
89
- console.log("shouldComponentUpdate nextState.mergedPropsUpdated",nextState.mergedPropsUpdated)
90
- */
91
- console . log ( "################## shouldComponentUpdate" , nextState . mergedPropsUpdated )
92
- console . log ( "################## shouldComponentUpdate" , nextState )
93
- return ! pure || nextState . mergedPropsUpdated
81
+ return true
94
82
}
95
83
96
84
constructor ( props , context ) {
@@ -171,12 +159,14 @@ export default function connect(mapStateToProps, mapDispatchToProps, mergeProps,
171
159
}
172
160
173
161
trySubscribe ( ) {
174
- console . log ( "trySubscribe" )
175
162
if ( shouldSubscribe && ! this . unsubscribe ) {
176
163
this . unsubscribe = this . store . subscribe ( ( ) => {
177
164
if ( ! this . unsubscribe ) {
178
165
return
179
166
}
167
+ if ( pure && ( this . store . getState ( ) === this . state . storeState ) ) {
168
+ return
169
+ }
180
170
this . handleChange ( false , false , true )
181
171
} )
182
172
}
@@ -197,12 +187,9 @@ export default function connect(mapStateToProps, mapDispatchToProps, mergeProps,
197
187
componentWillReceiveProps ( nextProps ) {
198
188
if ( pure ) {
199
189
const propsUpdated = ! shallowEqual ( nextProps , this . props )
200
- if ( propsUpdated ) {
201
- this . handleChange ( false , true , false )
202
- }
203
- else {
204
- this . skipNextRender = true ;
205
- }
190
+ propsUpdated ?
191
+ this . handleChange ( false , true , false ) :
192
+ this . skipNextRender = true
206
193
}
207
194
else {
208
195
this . handleChange ( false , true , false )
@@ -217,26 +204,19 @@ export default function connect(mapStateToProps, mapDispatchToProps, mergeProps,
217
204
clearCache ( ) {
218
205
this . finalMapDispatchToProps = null
219
206
this . finalMapStateToProps = null
207
+ this . skipNextRender = null
220
208
}
221
209
222
- handleChange ( isInit , isPropsChange , isStateChange ) {
223
- const result = tryCatch ( ( ) => this . doHandleChange ( isInit , isPropsChange , isStateChange ) )
210
+ handleChange ( isInit , isPropsChange , isStoreStateChange ) {
211
+ const result = tryCatch ( ( ) => this . doHandleChange ( isInit , isPropsChange , isStoreStateChange ) )
224
212
if ( result === errorObject ) {
225
- this . setState ( { error : errorObject . value } )
213
+ this . setState ( { handleChangeError : errorObject . value } )
226
214
}
227
215
}
228
216
229
- // TODO can we have a better method signature? it seems spread does not work?
230
- doHandleChange ( isInit , isPropsChange , isStateChange ) {
231
- console . log ( "################## handleChange for " + ( isInit ? "init" : isPropsChange ? "props" : "state" ) )
217
+ doHandleChange ( isInit , isPropsChange , isStoreStateChange ) {
232
218
233
- const storeState = this . store . getState ( )
234
- if ( isStateChange && pure && ( storeState === this . state . storeState ) ) {
235
- console . log ( "handleChange same state: return" )
236
- return
237
- }
238
-
239
- // This is put outside because it's used in both the fast and normal paths
219
+ // Put outside because it's used in both the fast and normal paths
240
220
let stateProps
241
221
let statePropsUpdated
242
222
const setStatePropsIfNeeded = ( props ) => {
@@ -245,66 +225,55 @@ export default function connect(mapStateToProps, mapDispatchToProps, mergeProps,
245
225
this . state . stateProps :
246
226
this . computeStateProps ( props )
247
227
statePropsUpdated = ! this . state . stateProps || ! shallowEqual ( stateProps , this . state . stateProps )
248
- console . log ( "stateProps" , stateProps )
249
- console . log ( "statePropsUpdated" , statePropsUpdated )
250
228
}
251
229
}
252
230
253
-
254
- // Fast track: bailout early because we don't need access to fresh props here
255
- console . log ( "isStateChange" , isStateChange )
256
- console . log ( "pure" , pure )
257
- console . log ( "!this.doStatePropsDependOnOwnProps" , ! this . doStatePropsDependOnOwnProps )
258
- if ( isStateChange && pure && ! this . doStatePropsDependOnOwnProps ) {
259
- setStatePropsIfNeeded ( this . props )
231
+ // Bail out early if we can
232
+ if ( isStoreStateChange && pure && ! this . doStatePropsDependOnOwnProps ) {
233
+ setStatePropsIfNeeded ( undefined ) // Props not needed here
260
234
if ( ! statePropsUpdated ) {
261
- console . log ( "-> fast track return" )
262
235
return
263
236
}
264
237
}
265
238
266
-
267
-
268
- const setStateFunction = ( previousState , currentProps ) => {
269
-
270
- console . log ( "-> normal track with props=" , currentProps )
271
-
272
- setStatePropsIfNeeded ( currentProps ) ;
239
+ const setStateFunction = ( prevState , props ) => {
240
+ // State props
241
+ setStatePropsIfNeeded ( props )
242
+ // Dispatch props
273
243
const dispatchProps = ( ! isInit && pure && isPropsChange && ! this . doDispatchPropsDependOnOwnProps ) ?
274
244
this . state . dispatchProps :
275
- this . computeDispatchProps ( currentProps )
245
+ this . computeDispatchProps ( props )
276
246
const dispatchPropsUpdated = ! this . state . dispatchProps || ! shallowEqual ( dispatchProps , this . state . dispatchProps )
277
- console . log ( "dispatchProps" , dispatchProps )
278
- console . log ( "dispatchPropsUpdated" , dispatchPropsUpdated )
279
-
280
- const mergedProps = ( statePropsUpdated || dispatchPropsUpdated || isPropsChange ) ?
281
- computeMergedProps ( stateProps , dispatchProps , currentProps ) :
282
- this . state . mergedProps
247
+ // Merged props
248
+ const mergedProps = ( ! statePropsUpdated && ! dispatchPropsUpdated && ! isPropsChange ) ?
249
+ this . state . mergedProps :
250
+ computeMergedProps ( stateProps , dispatchProps , props )
283
251
const mergedPropsUpdated = ! this . state . mergedProps || ! shallowEqual ( mergedProps , this . state . mergedProps )
284
- console . log ( "mergedProps" , mergedProps )
285
- console . log ( "mergedPropsUpdated" , mergedPropsUpdated )
252
+
253
+ // From there we already know if we should call render or not
254
+ if ( pure && ! mergedPropsUpdated ) {
255
+ this . skipNextRender = true
256
+ }
286
257
287
258
return {
288
- error : undefined ,
289
- storeState,
259
+ handleChangeError : undefined ,
260
+ storeState : this . store . getState ( ) ,
290
261
stateProps,
291
262
dispatchProps,
292
263
mergedProps,
293
264
mergedPropsUpdated
294
265
}
295
266
}
296
267
297
-
298
-
268
+ // See #86 and #368
269
+ // We need to avoid computng state multiple times per batch so we only run the last one
299
270
this . lastSetStateFunction = setStateFunction
300
- this . setState ( ( previousState , currentProps ) => {
301
- if ( this . lastSetStateFunction === setStateFunction ) {
302
- return setStateFunction ( previousState , currentProps )
303
- }
304
- else {
305
- return previousState
306
- }
307
- } ) ;
271
+ this . setState ( ( prevState , props ) => {
272
+ const isLast = this . lastSetStateFunction === setStateFunction
273
+ return isLast ?
274
+ setStateFunction ( prevState , props ) :
275
+ prevState
276
+ } )
308
277
309
278
}
310
279
@@ -316,24 +285,14 @@ export default function connect(mapStateToProps, mapDispatchToProps, mergeProps,
316
285
return this . refs . wrappedInstance
317
286
}
318
287
319
- getRenderedElementProps ( ) {
320
- if ( withRef ) {
321
- return {
322
- ...this . state . mergedProps ,
323
- ref : 'wrappedInstance'
324
- }
325
- }
326
- else {
327
- return this . state . mergedProps
328
- }
329
- }
330
-
331
288
render ( ) {
332
- console . log ( "################## render" )
333
- if ( this . state . error ) {
334
- throw this . state . error ;
289
+ if ( this . state . handleChangeError ) {
290
+ throw this . state . handleChangeError
335
291
}
336
- return createElement ( WrappedComponent , this . getRenderedElementProps ( ) )
292
+ const finalProps = withRef ?
293
+ ( { ...this . state . mergedProps , ref : 'wrappedInstance' } ) :
294
+ this . state . mergedProps
295
+ return createElement ( WrappedComponent , finalProps )
337
296
}
338
297
339
298
}
0 commit comments