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

has*_*tes 1 redux react-redux

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

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

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

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

设置清单

return {
        ...state,
        list: {
            ...state.list,
            ...action.list
        }
 };
Run Code Online (Sandbox Code Playgroud)

添加单个项目

return {
        ...state,
        list: {
            ...state.items,
            [action.item.id]: {
                ...state.list[action.item.id],
                ...action.item
            }
        }
 };
Run Code Online (Sandbox Code Playgroud)

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

有没有我可以抽象出这个代码,并为每个实体保留一个单独的reducer?

1ve*_*ven 5

您可以创建高阶减速器,它将负责为您创建减速器:

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;
  }
};
Run Code Online (Sandbox Code Playgroud)

基本上,我们正在创建一个函数,它将接受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
  })
);
Run Code Online (Sandbox Code Playgroud)

如果要在这些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);
Run Code Online (Sandbox Code Playgroud)