我已经规范了我正在处理的应用的状态(基于this article)并且我试图添加/删除部分状态树中的项目基于数量。
我的州树cart
的一部分全权负责存放购物车中的门票数量,按ID排列。当用户更改数量时,系统会调度UPDATE_QTY
,其中包含qty
和id
。
状态开始正确,因为传入的数据包含qty
但我似乎无法找出从cart
缩减器移除项目的语法qty
是0
,如果qty
为1或更多,也会重新添加。
有人可以就正确的语法提供建议吗?
编辑:我想知道我是否在UPDATE_QTY
操作中尝试做太多操作,并且我应该有单独的操作来删除和添加项目。
byId reducer
export function byId(state = initialState, action) {
switch (action.type) {
case SET_INITIAL_CART_DATA:
return Object.assign({}, state, action.tickets);
case UPDATE_QTY: // Here, I need to check if action.qty is 0 and if it is I need to remove the item but also add it back in if action.qty > 0
return {
...state,
[action.id]: { ...state[action.id], qty: action.qty }, // Updating the qty here works fine
};
default:
return state;
}
}
Simplfied状态树
const state = {
cart: {
byId: {
'40': { // How can I remove these items when qty is 0 or add back in if > 0?
qty: 0,
id: '40'
},
'90': {
qty: 0,
id: '90'
}
},
allIds: [
[
'40',
'90',
]
]
},
}
我还需要在我的allIds
缩减器中反映ID。
allIds reducer
export function allIds(state = [], action) {
switch (action.type) {
case SET_INITIAL_CART_DATA:
return [...state, ...action.allIds];
case UPDATE_QTY:
return [ONLY IDS WITH QTY]
default:
return state;
}
}
为此,我不确定allIds
减速器是否需要连接到byIds
减速器并从那里获取信息。我很想知道这样的事情的最佳实践。
答案 0 :(得分:0)
为什么byIds
和allIds
有单独的缩减器?我会将这些合并到一个cart
缩减器中,并将allIds
状态保持为byIds
:
case SET_INITIAL_CART_DATA:
// just guessing here...
const { tickets } = action;
const allIds = tickets
.reduce((arr, ticket) => arr.concat(ticket.id), []);
return {
byIds: { ...tickets },
allIds
}
case UPDATE_QTY: {
const { byIds, allIds } = state;
const { id, qty } = action;
const idx = allIds.indexOf(id);
const next = { };
if (qty > 0) {
next.byIds = {
...byIds,
[id]: { id, qty }
};
next.allIds = idx === -1 ? allIds.concat(id) : [ ...allIds ];
return next;
}
next.byIds = { ...byIds };
delete next.byIds[id];
next.allIds = idx === -1 ? [ ...allIds ] : [
...allIds.slice(0, idx),
...allIds.slice(idx + 1)
];
return next;
}
但是,你想要哪种状态归一化?如果这代表购物车的购物车,那么门票将被标准化,并且购物车将仅代表要购买的门票的数量。然后你的州看起来像这样:
{
tickets: {
byIds: {
'1': { id, name, price, ... },
'2': { ... },
'3': { ... },
...
}
allIds: [ '1', '2', '3', ... ]
},
cart: [
{ id: 2, qty: 2 },
{ id: 1, qty: 1 }
]
}
使用数组作为购物车状态可以维持广告订单。
答案 1 :(得分:0)
有时候(当您仅遍历id并通过id获取时)足以从allId中删除id并跳过所有不必要的计算。
case actionTypes.DELETE_ITEM: {
const filteredIds = state.allIds.filter(id => id !== action.itemId);
return {
...state,
allIds: filteredIds
};
}