Skip to content

Instantly share code, notes, and snippets.

@gaearon
Last active April 18, 2019 01:24
Show Gist options
  • Save gaearon/f79df1faa59e502f98ab to your computer and use it in GitHub Desktop.
Save gaearon/f79df1faa59e502f98ab to your computer and use it in GitHub Desktop.
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
}
}
@CrocoDillon
Copy link

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 :)

state = counters(state, { type: '@@redux/INIT' }) // { a: 0, b: 0, c: 0 }

@nikgraf
Copy link

nikgraf commented Jan 30, 2016

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