我喜欢Redux中的reducer组合概念,但是遇到了我想拆分reducer的场景,但是孩子们还是会依赖其他的状态切片进行更改.
例如
在我的州,我需要跟踪以下内容:
>一系列可能的等级(即[2,3,4,5,6])
>当前选择的排名(上述值之一).
>取决于所选等级,一系列可能的训练水平.关系是范围从[1 ..(selectedRank – 1)]
>目前选择的训练水平在上述范围内
最初,我有一个更大的减速器,它封装了所有这些方面:
function rankAndTraining(state = { selectedRank : 4,availableRanks : [ 2,6 ],availableTrainingLevels : [ 1,2,3 ],selectedTrainingLevel : 2,},action) { . . . case SELECT_RANK: let newRank = action.rank; if(!availableRanks.contains(newRank)) { // If new rank is not an allowed value,do nothing. return state; } // Update selectedRank with newRank... // Update availableTrainingLevels array based on newRank... // [ 1 ... (selectedRank - 1) ] // Update selectedTrainingLevel if it is now out of range // of availableTrainingLevel (i.e. set to highest value of new range) return state; . . . }
我想把这个减速器分开,因为我觉得等级和训练水平可以保持在单独的减速器中.
但是,如果拆分缩减器,则仍需要处理整个状态块的依赖关系,例如:
>如果新排名无效(例如,它不在availableRanks中),则不应更新训练级别位.
如果我将训练级别比特分成另一个减速器,那么他们将无法知道这种“等级检查”的结果,因为他们在状态切片中“看到”的是训练级别的部分.
在这种情况下,鉴于它们之间的依赖关系,上面的reducer真的是我可以得到的状态的“最小切片”吗?或者有没有更好的方法来拆分它,我可能没有看到?
解决方法
如果您使用Redux thunk中间件,您可以在实际调度操作之前先检查整个状态,而不是调度您的操作,然后在reducer中有条件地更新您的状态:
function selectRankIfAllowed() { return (dispatch,getState) => { const { availableRanks } = getState(); if(!availableRanks.contains(newRank)) { // If new rank is not an allowed value,do nothing. return state; } dispatch(selectRank()); }; }