【问题标题】:How to abstract Multiple reducers with similar actions如何抽象多个具有相似动作的减速器
【发布时间】:2017-10-26 01:59:09
【问题描述】:

我的应用程序中有多个实体。每个实体都独立于其他实体。所以我为每个实体创建了一个单独的reducer,并在创建商店时将它们组合起来。

每个条目都有一些常见的操作,例如

1) 设置项目列表 2) 添加单项 3)更新单品 4) 删除单个项目

几乎在每个减速器中我都有相同类型的代码重复

设置列表

return {
        ...state,
        list: {
            ...state.list,
            ...action.list
        }
 };

添加单个项目

return {
        ...state,
        list: {
            ...state.items,
            [action.item.id]: {
                ...state.list[action.item.id],
                ...action.item
            }
        }
 };

..更新操作和删除操作的类似代码

有没有一种方法可以抽象出这段代码,并且仍然为每个实体保留一个单独的 reducer?

【问题讨论】:

    标签: redux react-redux


    【解决方案1】:

    您可以创建Higher Order Reducer,它将负责为您创建reducer:

    const createEntityReducer = constants => (state = {}, action) => {
      switch (action.type) {
        case constants.set:
          return {
            ...state,
            list: {
              ...state.list,
              ...action.list
            }
          };
        case constants.add:
          return {
            ...state,
            list: {
              ...state.items,
              [action.item.id]: {
                ...state.list[action.item.id],
                ...action.item
              }
            }
          };
        default:
          return state;
      }
    };
    

    基本上,我们正在创建一个函数,它将接受constants 对象并返回新的reducer,它会改变状态,当相应的动作将被分派时。

    接下来,您可以根据需要创建尽可能多的相似化简器:

    const entityReducer = createEntityReducer({
      set: "SET_ACTION_TYPE",
      add: "ADD_ACTION_TYPE"
    });
    
    const entityReducer2 = createEntityReducer({
      set: "SET_ACTION_TYPE_2",
      add: "ADD_ACTION_TYPE_2"
    });
    
    const store = createStore(
      combineReducers({
        entityReducer,
        entityReducer2
      })
    );
    

    如果您想在这些 reducer 中处理自定义操作,您可以为此创建另一个 Higher Order Reducer:

    const withCustomActions = (reducer) => (state, action) => {
      // that's the state, returned from initial reducer
      const nextState = reducer(state, action);
    
      switch (action.type) {
        case "CUSTOM_ACTION":
          return {
            ...nextState,
            key: action.value
          };
        default:
          return nextState;
      }
    }
    
    const entityReducer3 = withCustomActions(entityReducer);
    

    【讨论】:

    • 感谢 1ven,如果我们以这种方式创建减速器,我如何添加特定于该实体减速器的其他操作,有没有简单的方法来扩展它?
    • @hashbytes 是的,这很简单。我已经更新了答案
    猜你喜欢
    • 2017-11-22
    • 1970-01-01
    • 2020-02-03
    • 2023-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-03
    相关资源
    最近更新 更多