-
-
Save jamesplease/09e1e1f3f08113acec60e093dd5e42f3 to your computer and use it in GitHub Desktop.
This file contains 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
export default function composeReducers(reducers) { | |
return (state, action) => { | |
let reducerCount = reducers.length; | |
let sideEffects = []; | |
let noUpdateCount = 0; | |
const reducedResult = reducers.reduceRight((prevState, reducer, index) => { | |
// This is to handle the asymmetry in the useReducerWithSideFffect API. | |
// Whereas regular reducers have a symmetric API that is state in, state out | |
// useReducerWithSideEffects has state in, state+sideEffects out | |
let state; | |
if (index === reducerCount - 1) { | |
state = prevState; | |
} else { | |
state = prevState.newState; | |
} | |
const result = reducer(state, action); | |
const isNoUpdate = typeof result === 'symbol'; | |
let returnValue; | |
if (isNoUpdate) { | |
noUpdateCount++; | |
// If this is the last reducer and we have no update, then we must | |
// return the return value of the reducer, which is a Symbol. | |
// That way, we can return it from the entire composed reducer. | |
if (index === 0 && noUpdateCount === reducerCount) { | |
returnValue = result; | |
} | |
// Otherwise, we must NOT return the Symbol, or else this loop will crash. | |
else { | |
returnValue = { | |
newState: state, | |
}; | |
} | |
} | |
// If the return value is not a symbol, then we always just return whatever | |
// the reducer gave us. | |
else { | |
returnValue = result; | |
} | |
if (result && Array.isArray(result.newSideEffect)) { | |
sideEffects = sideEffects.concat(result.newSideEffect); | |
} | |
return returnValue; | |
}, state); | |
const noUpdateOccurred = noUpdateCount === reducerCount; | |
if (noUpdateOccurred) { | |
return reducedResult; | |
} | |
return { | |
newState: reducedResult && reducedResult.newState, | |
newSideEffect: sideEffects, | |
}; | |
}; | |
} |
Yup! It behaves just like Redux’s composeReducers
in that (and every other) regard.
ah .yeah, its been so loong since ive reeduxed makes sense, the gist looks good? would definitely ttake pr
Nice. I’ll whip somethin’ up
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
if i have n reducers and the final one returns no update would my expecation be to get the updates from the first say 8/9 reducers? I would think so?