Лучший способ в React обновить свойство в массиве объектов

0

Я создаю простую корзину покупок для сайта и работаю над действиями 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})
},
  • 0
    вы используете es6?
  • 0
    Да, используя Бабель, чтобы перенести
Теги:
functional-programming

2 ответа

1
Лучший ответ

Поскольку вы используете 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});
        }
}

полный рабочий пример

0

Я думаю, что так лучше:

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,
})

Ещё вопросы

Сообщество Overcoder
Наверх
Меню