Я создаю простую корзину покупок для сайта и работаю над действиями add to cart
. Пока я работаю, я чувствую, что есть, вероятно, простой и элегантный способ сделать это.
Это начальное состояние:
start_state = {
inventory: [
{sku: "product_1", price: 600, name: "Product 1"},
{sku: "product_2", price: 800, name: "Product 2"}
],
cart: []
}
И это желаемое конечное состояние:
start_state = {
inventory: [
{sku: "product_1", price: 600, name: "Product 1"},
{sku: "product_2", price: 800, name: "Product 2"}
],
cart: [
{sku: "product_1", quantity: 2},
{sku: "product_2", quantity: 1}
]
}
И это функция Im, запускающая переход от исходного состояния к новому final_state, аргумент sku
- это элемент из состояния, которое передается при вызове действия:
addToCart: function (sku) {
let currentCart = this.state.cart
let itemInCart = _.findIndex(currentCart, ['sku', sku])
let newItem = { sku: sku }
if (itemInCart !== -1) {
let newQuantity = currentCart[itemInCart].quantity
newItem.quantity = newQuantity + 1
} else {
newItem.quantity = 1
}
let filteredCart = _.filter(currentCart, (item) => { return item.sku !== sku })
let newCart = _.concat(filteredCart, newItem)
this.setState({cart: newCart})
},
Поскольку вы используете ES6, вы можете использовать некоторые из своих новых функций, таких как findIndex
и Object.assign
для достижения того, чего вы хотите.
addToCart: function(product) {
let index = this.state.cart.findIndex((x) => x.sku === product.sku);
if(index === -1) {
let newProduct = {sku: product.sku, quantity:1}
this.setState({cart : this.state.cart.concat([newProduct])})
}
else {
let newCart = Object.assign([], this.state.cart);
newCart[index].quantity = newCart[index].quantity+1;
this.setState({cart: newCart});
}
}
Я думаю, что так лучше:
function getCardWithIncItem(currentCart, itemInCart) {
return [
...currentCart.slice(0, itemInCart),
Object.assign({}, currentCart[itemInCart], {
quantity: currentCart[itemInCart].quantity + 1,
}),
...currentCart.slice(itemInCart + 1),
];
}
function getCardWithNewItem(currentCart, sku) {
return [
...currentCart, {
sku: sku,
quantity: 1,
}
];
}
const currentCart = this.state.cart;
const itemInCart = _.findIndex(currentCart, ['sku', sku]);
const newCart = (itemInCart !== -1)
? getCardWithIncItem(currentCart, itemInCart)
: getCardWithIncItem(currentCart, sku);
this.setState({
cart: newCart,
})