我的应用程序中有多个实体。每个实体都独立于其他实体。所以我为每个实体创建了一个单独的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?
答案 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);