如何使用类似的操作抽象多个reducer

时间:2017-10-26 01:59:09

标签: redux react-redux

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

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

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

在每个reducer中我都有相同类型的代码重复

设置列表

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

添加单件

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

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

我是否可以抽象出这段代码并为每个实体保留一个单独的reducer?

1 个答案:

答案 0 :(得分:5)

您可以创建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中处理自定义操作,可以为此创建另一个高阶减速器:

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