Last active
April 18, 2019 01:24
-
-
Save gaearon/f79df1faa59e502f98ab to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function counterA(state = 0, action) { | |
switch (action.type) { | |
case 'increment': | |
return state + 1 | |
case 'decrement': | |
return state - 1 | |
default: | |
return state | |
} | |
} | |
function counterB(state = 0, action) { | |
switch (action.type) { | |
case 'increment': | |
return state + 10 | |
case 'decrement': | |
return state - 10 | |
default: | |
return state | |
} | |
} | |
function* counterC(state = 0, action) { | |
const a = yield counterA | |
const b = yield counterB | |
return state + Math.abs(a - b) | |
} | |
const counters = combineReducers({ | |
a: counterA, | |
b: counterB, | |
c: counterC | |
}) | |
let state | |
state = counters(state, { type: 'increment' }) // { a: 0, b: 0, c: 0 } | |
state = counters(state, { type: 'increment' }) // { a: 1, b: 10, c: 9 } | |
state = counters(state, { type: 'increment' }) // { a: 2, b: 20, c: 27 } | |
state = counters(state, { type: 'decrement' }) // { a: 1, b: 10, c: 36 } | |
state = counters(state, { type: 'decrement' }) // { a: 0, b: 0, c: 36 } | |
// Note: very naive | |
function combineReducers(reducers) { | |
return (state = {}, action) => { | |
let nextState = {} | |
let resolve = (key) => { | |
if (nextState.hasOwnProperty(key)) { | |
return | |
} | |
const result = reducers[key](state[key], action) | |
if (typeof result.next !== 'function') { | |
nextState[key] = result | |
return | |
} | |
let item = result.next() | |
while (!item.done) { | |
const dependencyKey = Object.keys(reducers).find(key => | |
reducers[key] === item.value | |
) | |
resolve(dependencyKey) | |
item = result.next(nextState[dependencyKey]) | |
} | |
nextState[key] = item.value | |
} | |
for (const [key, reducer] of Object.entries(reducers)) { | |
resolve(key) | |
} | |
return nextState | |
} | |
} |
huh, nice! probably not needed often, but definitely comes in handy in some edge cases
When used in larger application this could make it hard to understand the effects of an action. In case of actions written by co-workers where I don't know the effects: I can do a text-search in my editor and see in which place a certain action is triggered as well as which reducers and even sagas make use of it. Easy to follow the flow.
Debugging tools could help here in case they not only show the triggered action, but also which reducers actually changed the state.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The first action should be a dummy action if you want to get that result (
{ a: 0, b: 0, c: 0 }
) back. Details but whatever :)