我有这种形式的状态树:
const initialState = {
total: 0,
discount: 0,
typeDiscount: 0,
products: data
};
其中product字段是一个数组,而该数组是这样的:
[{
"id":9090,
"name":"Item1",
"price":200,
"discount":10,
"type":"fiction",
"quantity": 1,
"img_url":"https://store.lexisnexis.com.au/__data/media/catalog/thumb//placeholder.jpg"
},
{
"id":9091,
"name":"Item2",
"price":250,
"discount":15,
"type":"literature",
"quantity": 1,
"img_url":"https://store.lexisnexis.com.au/__data/media/catalog/thumb//placeholder.jpg"
}]
现在我正在尝试更改该数组中的数量,我是Redux的新手,所以请指导我如何执行此操作?
这是我的减速器:
case types.ADD_ITEM_CART:
let product_add = state.products
for (let i = 0; i < product_add.length; i++) {
if (product_add[i].id === action.id) {
product_add[i].quantity = product_add[i].quantity + 1
break
}
}
return dotProp.set(state, `products`, product_add);
答案 0 :(得分:5)
您可以使用Array.prototype.map遍历项目,并从有效载荷中更新与id
匹配的项目。
类似的东西:
const state = [{
"id": 9090,
"name": "Item1",
"price": 200,
"discount": 10,
"type": "fiction",
"quantity": 1,
"img_url": "https://store.lexisnexis.com.au/__data/media/catalog/thumb//placeholder.jpg"
},
{
"id": 9091,
"name": "Item2",
"price": 250,
"discount": 15,
"type": "literature",
"quantity": 1,
"img_url": "https://store.lexisnexis.com.au/__data/media/catalog/thumb//placeholder.jpg"
}
];
const payload = {
id: 9091
};
const nextState = state.map(product => {
if (product.id !== payload.id) {
// not our product, return as is
return product;
}
return {
...product,
quantity: product.quantity + 1
}
});
console.log(nextState);
.as-console-wrapper {
max-height: 100% !important;
}
要删除项目,您只需使用Array.prototype.filter:
const state = [{
"id": 9090,
"name": "Item1",
"price": 200,
"discount": 10,
"type": "fiction",
"quantity": 1,
"img_url": "https://store.lexisnexis.com.au/__data/media/catalog/thumb//placeholder.jpg"
},
{
"id": 9091,
"name": "Item2",
"price": 250,
"discount": 15,
"type": "literature",
"quantity": 1,
"img_url": "https://store.lexisnexis.com.au/__data/media/catalog/thumb//placeholder.jpg"
}
];
const payload = {
id: 9091
};
const nextState = state.filter(product => product.id !== payload.id);
console.log(nextState);
答案 1 :(得分:2)
使用价差运算符...
和array.map()
,您可以创建一个新产品数组,在为您创建新产品对象时,所有与ID不匹配的产品都将保留相同的对象引用感兴趣的产品:
case types.ADD_ITEM_CART:
const updatedProducts = state.products.map(product => {
if (product.id === action.id) {
const newQuantity = product.quantity + 1;
return { ...product, quantity: newQuantity };
}
return product;
})
return { ...state, products: updatedProducts };
}
编辑:使用array.filter()
方法可以轻松实现删除,该方法将创建一个仅包含与谓词函数匹配的项目的新数组;在这种情况下,所有与您要删除的产品ID不匹配的产品:
case types.REMOVE_ITEM_CART:
const updatedProducts = state.products.filter(product => product.id !== action.id)
return { ...state, products: updatedProducts };
}
答案 2 :(得分:2)
请勿像Redux或React本身那样改变您的状态。复制对象不会创建其他对象。如果您为新的属性更改属性,则也会对原始属性进行变异。
通常,我们使用Object.assign
或扩展语法结合.map
,.filter
之类的方法。 Object.assign
或传播语法也不会创建完全不同的对象。他们创建浅拷贝,这意味着一层拷贝。如果您为新对象更改了嵌套属性,则再次更改原始对象。因此,请结合所有这些工具。
case types.ADD_ITEM_CART: {
// We are mapping our related array.
const newProducts = state.products.map( el => {
// If id does not match, return the element without doing nothing.
if ( el.id !== action.id ) { return el };
// id match, increment the quantity.
return { ...el, quantity: el.quantity + 1 };
})
// Lastly, return our state again without mutating it.
return { ...state, products: newProducts };
}
如果要从数组中删除项目,通常为此使用.filter
方法。
const newProducts = state.products.filter( el => el.id !== action.id );
return { ...state, products: newProducts };