Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0cc063b

Browse files
committed
Merge pull request#348 from reactjs/bailout
Bail out if stateProps can be calculated early and did not change
2 parentsa0947cf +388c050 commit0cc063b

File tree

2 files changed

+63
-6
lines changed

2 files changed

+63
-6
lines changed

‎src/components/connect.js‎

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ export default function connect(mapStateToProps, mapDispatchToProps, mergeProps,
219219
this.mergedProps=null
220220
this.haveOwnPropsChanged=true
221221
this.hasStoreStateChanged=true
222+
this.haveStatePropsBeenPrecalculated=false
222223
this.renderedElement=null
223224
this.finalMapDispatchToProps=null
224225
this.finalMapStateToProps=null
@@ -229,13 +230,21 @@ export default function connect(mapStateToProps, mapDispatchToProps, mergeProps,
229230
return
230231
}
231232

232-
constprevStoreState=this.state.storeState
233233
conststoreState=this.store.getState()
234+
constprevStoreState=this.state.storeState
235+
if(pure&&prevStoreState===storeState){
236+
return
237+
}
234238

235-
if(!pure||prevStoreState!==storeState){
236-
this.hasStoreStateChanged=true
237-
this.setState({ storeState})
239+
if(pure&&!this.doStatePropsDependOnOwnProps){
240+
if(!this.updateStatePropsIfNeeded()){
241+
return
242+
}
243+
this.haveStatePropsBeenPrecalculated=true
238244
}
245+
246+
this.hasStoreStateChanged=true
247+
this.setState({ storeState})
239248
}
240249

241250
getWrappedInstance(){
@@ -251,11 +260,13 @@ export default function connect(mapStateToProps, mapDispatchToProps, mergeProps,
251260
const{
252261
haveOwnPropsChanged,
253262
hasStoreStateChanged,
263+
haveStatePropsBeenPrecalculated,
254264
renderedElement
255265
}=this
256266

257267
this.haveOwnPropsChanged=false
258268
this.hasStoreStateChanged=false
269+
this.haveStatePropsBeenPrecalculated=false
259270

260271
letshouldUpdateStateProps=true
261272
letshouldUpdateDispatchProps=true
@@ -269,7 +280,9 @@ export default function connect(mapStateToProps, mapDispatchToProps, mergeProps,
269280

270281
lethaveStatePropsChanged=false
271282
lethaveDispatchPropsChanged=false
272-
if(shouldUpdateStateProps){
283+
if(haveStatePropsBeenPrecalculated){
284+
haveStatePropsChanged=true
285+
}elseif(shouldUpdateStateProps){
273286
haveStatePropsChanged=this.updateStatePropsIfNeeded()
274287
}
275288
if(shouldUpdateDispatchProps){

‎test/components/connect.spec.js‎

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1082,7 +1082,6 @@ describe('React', () => {
10821082
)
10831083
spy.destroy()
10841084

1085-
10861085
spy=expect.spyOn(console,'error')
10871086
TestUtils.renderIntoDocument(
10881087
<ProviderMockstore={store}>
@@ -1547,6 +1546,51 @@ describe('React', () => {
15471546
expect(renderCalls).toBe(1)
15481547
})
15491548

1549+
it('should bail out early if mapState does not depend on props',()=>{
1550+
conststore=createStore(stringBuilder)
1551+
letrenderCalls=0
1552+
letmapStateCalls=0
1553+
1554+
@connect(state=>{
1555+
mapStateCalls++
1556+
returnstate==='aaa' ?{change:1} :{}
1557+
})
1558+
classContainerextendsComponent{
1559+
render(){
1560+
renderCalls++
1561+
return<Passthrough{...this.props}/>
1562+
}
1563+
}
1564+
1565+
TestUtils.renderIntoDocument(
1566+
<ProviderMockstore={store}>
1567+
<Container/>
1568+
</ProviderMock>
1569+
)
1570+
1571+
expect(renderCalls).toBe(1)
1572+
expect(mapStateCalls).toBe(1)
1573+
1574+
constspy=expect.spyOn(Container.prototype,'setState').andCallThrough()
1575+
1576+
store.dispatch({type:'APPEND',body:'a'})
1577+
expect(mapStateCalls).toBe(2)
1578+
expect(renderCalls).toBe(1)
1579+
expect(spy.calls.length).toBe(0)
1580+
1581+
store.dispatch({type:'APPEND',body:'a'})
1582+
expect(mapStateCalls).toBe(3)
1583+
expect(renderCalls).toBe(1)
1584+
expect(spy.calls.length).toBe(0)
1585+
1586+
store.dispatch({type:'APPEND',body:'a'})
1587+
expect(mapStateCalls).toBe(4)
1588+
expect(renderCalls).toBe(2)
1589+
expect(spy.calls.length).toBe(1)
1590+
1591+
spy.destroy()
1592+
})
1593+
15501594
it('should allow providing a factory function to mapStateToProps',()=>{
15511595
letupdatedCount=0
15521596
letmemoizedReturnCount=0

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp