我想将一个减速器分成N个,再将1个键组合在一起。
说我有一个初始状态:
const STATE_INITIAL = {
nested_component: {
field1: 1,
field2: 2
},
upper_field: 3
}
然后我有一个减速器:
function reducer(state=STATE_INITIAL, action){
switch(action){
case ACTION_UPPER_FIELD:
return ...
case ACTION_GRID1:
return ...
case ACTION_GRID2:
return ...
default:
return state;
}
}
我为什么要这样做?
我希望有一个可以在整个项目中重复使用的组件。它总是带有它的初始状态,并且它的减速器我想要连接到应用程序的其余部分。
我的解决方案
我能想到的一种方法是为网格操作堆叠case
,为其提供state.grid
及其自己的初始状态,并将结果与state
结合起来:
const STATE_INITIAL = {
nested_component: {},
upper_field: 3
};
function reducer(state=STATE_INITIAL, action){
switch(action){
case ACTION_UPPER_FIELD:
return ...
case ACTION_GRID1:
case ACTION_GRID2:
return reducerGrid(state.grid, action);
default:
return state;
}
}
const STATE_INITIAL_GRID = {
field1: 1,
field2: 2
};
function reducerGrid(state = STATE_INITIAL_GRID, action) {
switch(action){
case ACTION_GRID1:
return ...
case ACTION_GRID2:
return ...
default:
return state;
}
}
是否有标准化方法或我的解决方案是否合适?我不喜欢的事情是default
中的reducerGrid
现在似乎多余了,我也不满意必须在两个缩减器中重复这些操作。
我的第二个解决方案
function reducer(state=STATE_INITIAL, action){
const stateGrid = reducerGrid(state.grid, action)
let stateNew = state;
if(stateGrid !== state.grid){
stateNew = {...state, grid: ...stateGrid}
}
switch(action){
case ACTION_UPPER_FIELD:
return {...stateNew, ... };
default:
return stateNew;
}
}
第三个解决方案
function reducer(state=STATE_INITIAL, action){
const stateNew = {...state, grid: ...reducerGrid(state.grid, action)};
switch(action){
case ACTION_UPPER_FIELD:
return ...
default:
return stateNew;
}
}
答案 0 :(得分:1)
我终于找到了一个我满意的解决方案。
使用此方法:
import R from 'ramda';
function splitReducers(reducers, rest) {
return (state, action) => {
const reducersPrepared = R.mapObjIndexed((reducer, key) => {
return reducer(R.defaultTo({}, state)[key], action);
})(reducers);
const getUndefinedIfEmpty = R.ifElse(
R.isEmpty,
() => undefined,
R.identity
);
const stateWithoutSplitKeys = R.pipe(
R.omit(R.keys(reducers)),
getUndefinedIfEmpty
)(state);
return R.merge(
reducersPrepared,
rest(stateWithoutSplitKeys, action)
);
}
}
我可以通过以下方式编写州树:
Ports: splitReducers({
grid: reducerGrid,
}, reducer);
这将导致对象分裂:
{
Ports: {
grid: {...},
isSaving: true,
isVisible: false
}
}
应用该方法后,root-reducer
乍看之下显示更多状态:
export const rootReducer = combineReducers({
pageAllocation: combineReducers({
tabNetwork: combineReducers({
popupNetworkTemplates: reducerPopupNetworkTemplates,
gridPorts: splitReducers({ // <----- HERE IT IS
grid: reducerGridPortsOnly
}, reducerPorts),
}),
tabStorage: () => ({}),
activeTab: reducerPortsActiveTab
}),