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) {
113
113
throw sanityError ;
114
114
}
115
115
116
+ var hasChanged = false ;
116
117
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' ) {
119
121
var errorMessage = getUndefinedStateErrorMessage ( key , action ) ;
120
122
throw new Error ( errorMessage ) ;
121
123
}
122
- return newState ;
124
+ hasChanged = hasChanged || nextStateForKey !== previousStateForKey ;
125
+ return nextStateForKey ;
123
126
} ) ;
124
127
125
128
if ( process . env . NODE_ENV !== 'production' ) {
@@ -129,6 +132,6 @@ export default function combineReducers(reducers) {
129
132
}
130
133
}
131
134
132
- return finalState ;
135
+ return hasChanged ? finalState : state ;
133
136
} ;
134
137
}
Original file line number Diff line number Diff line change @@ -112,6 +112,45 @@ describe('Utils', () => {
112
112
expect ( reducer ( { counter : 0 } , { type : increment } ) . counter ) . toEqual ( 1 ) ;
113
113
} ) ;
114
114
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
+
115
154
it ( 'should throw an error on first call if a reducer attempts to handle a private action' , ( ) => {
116
155
const reducer = combineReducers ( {
117
156
counter ( state , action ) {
You can’t perform that action at this time.
0 commit comments