File tree Expand file tree Collapse file tree 2 files changed +46
-4
lines changed
Expand file tree Collapse file tree 2 files changed +46
-4
lines changed Original file line number Diff line number Diff line change @@ -113,13 +113,16 @@ export default function combineReducers(reducers) {
113113 throw sanityError ;
114114 }
115115
116+ var hasChanged = false ;
116117 var finalState = mapValues ( finalReducers , ( reducer , key ) => {
117- var newState = reducer ( state [ key ] , action ) ;
118- if ( typeof newState === 'undefined' ) {
118+ var previousStateForKey = state [ key ] ;
119+ var nextStateForKey = reducer ( previousStateForKey , action ) ;
120+ if ( typeof nextStateForKey === 'undefined' ) {
119121 var errorMessage = getUndefinedStateErrorMessage ( key , action ) ;
120122 throw new Error ( errorMessage ) ;
121123 }
122- return newState ;
124+ hasChanged = hasChanged || nextStateForKey !== previousStateForKey ;
125+ return nextStateForKey ;
123126 } ) ;
124127
125128 if ( process . env . NODE_ENV !== 'production' ) {
@@ -129,6 +132,6 @@ export default function combineReducers(reducers) {
129132 }
130133 }
131134
132- return finalState ;
135+ return hasChanged ? finalState : state ;
133136 } ;
134137}
Original file line number Diff line number Diff line change @@ -112,6 +112,45 @@ describe('Utils', () => {
112112 expect ( reducer ( { counter : 0 } , { type : increment } ) . counter ) . toEqual ( 1 ) ;
113113 } ) ;
114114
115+ it ( 'should maintain referential equality if the reducers it is combining do' , ( ) => {
116+ const reducer = combineReducers ( {
117+ child1 ( state = { } ) {
118+ return state ;
119+ } ,
120+ child2 ( state = { } ) {
121+ return state ;
122+ } ,
123+ child3 ( state = { } ) {
124+ return state ;
125+ }
126+ } ) ;
127+
128+ const initialState = reducer ( undefined , '@@INIT' ) ;
129+ expect ( reducer ( initialState , { type : 'FOO' } ) ) . toBe ( initialState ) ;
130+ } ) ;
131+
132+ it ( 'should not have referential equality if one of the reducers changes something' , ( ) => {
133+ const reducer = combineReducers ( {
134+ child1 ( state = { } ) {
135+ return state ;
136+ } ,
137+ child2 ( state = { count : 0 } , action ) {
138+ switch ( action . type ) {
139+ case 'increment' :
140+ return { count : state . count + 1 } ;
141+ default :
142+ return state ;
143+ }
144+ } ,
145+ child3 ( state = { } ) {
146+ return state ;
147+ }
148+ } ) ;
149+
150+ const initialState = reducer ( undefined , '@@INIT' ) ;
151+ expect ( reducer ( initialState , { type : 'increment' } ) ) . toNotBe ( initialState ) ;
152+ } ) ;
153+
115154 it ( 'should throw an error on first call if a reducer attempts to handle a private action' , ( ) => {
116155 const reducer = combineReducers ( {
117156 counter ( state , action ) {
You can’t perform that action at this time.
0 commit comments