用于依赖状态切片的Redux减速器/状态设计

时间:2015-10-29 07:22:58

标签: javascript redux reducers

我喜欢Redux中的reducer组合概念,但是我遇到了喜欢来拆分reducer的场景,但是孩子们还是依赖于其他的状态切片做出改变。

例如

在我的州,我需要跟踪以下内容:

  • 一系列可能的排名(即[ 2, 3, 4, 5, 6 ]
  • 当前选定的排名(上述值之一)。
  • 取决于所选等级,可能的培训级别。关系是范围来自[ 1 .. (selectedRank - 1) ]
  • 目前在
  • 范围内选择的培训级别

最初,我有一个更大的减速器,它封装了所有这些方面:

function rankAndTraining(state = {
  selectedRank            : 4,
  availableRanks          : [ 2, 3, 4, 5, 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 中),则不应更新培训级别位。

如果我将训练级别的比特分成另一个减速器,那么他们将无法知道这个“等级检查”的结果,因为他们所有人都会“看到”他们的状态-slice是培训级别件。

在这种情况下,鉴于它们之间的依赖关系,上面的reducer真的是我能得到的状态的“最小切片”吗?或者有没有更好的方法来拆分我可能没有看到的?

1 个答案:

答案 0 :(得分:3)

如果您使用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());
  };
}

https://github.com/gaearon/redux-thunk