-
Notifications
You must be signed in to change notification settings - Fork 122
/
Copy pathcombineReducers.js
41 lines (36 loc) · 1.08 KB
/
combineReducers.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import { loop, isLoop, getEffect, getModel } from './loop';
import { batch, none } from './effects';
import { mapValues } from './utils';
function optimizeBatch(effects) {
switch(effects.length) {
case 0:
return none();
case 1:
return effects[0];
default:
return batch(effects);
}
}
export function combineReducers(reducerMap) {
return function finalReducer(state = {}, action) {
const effects = [];
let hasChanged = false;
const model = mapValues(reducerMap, (reducer, key) => {
const previousStateForKey = state[key];
const nextStateForKey = reducer(previousStateForKey, action);
if (isLoop(nextStateForKey)) {
effects.push(getEffect(nextStateForKey));
const model = getModel(nextStateForKey);
hasChanged = hasChanged || model !== previousStateForKey;
return model;
} else {
hasChanged = hasChanged || nextStateForKey !== previousStateForKey;
return nextStateForKey;
}
});
return loop(
hasChanged ? model : state,
optimizeBatch(effects)
);
};
}