Сокращение добавления элемента к существующему объекту в состоянии дублирует запись

#reactjs #redux #lodash

#reactjs #redux #Lodash

Вопрос:

Я использую redux и Lodash для добавления товара в корзину. По какой-то причине он дублирует запись. Итак, у меня есть один и тот же элемент в объекте cart и объекте cart.items

Мой редуктор:

 const INITIAL_STATE = {
    items: {},
    count: null
}

export default (state = INITIAL_STATE, action) => {
    switch (action.type) {
    case actionTypes.ADD_CART_ITEM:
        return { ...state, ..._.merge(state.items, { [action.payload.id]: action.payload }) }
    default:
        return state
    }
}
  

Мое действие

 export const addCartItem = (item) => {
    return {
        type: actionTypes.ADD_CART_ITEM,
        payload: item
    }
}
  

Моя функция для добавления в корзину

 addToCart() {
        const { selectedSize, selectedShade, selectedQuantity } = this.props.product
        const { id, sku } = this.props.product.product

        if (selectedSize amp;amp; selectedShade amp;amp; selectedQuantity) {
            const item = {
                id: id,
                sku: sku,
                size: selectedSize,
                shade: selectedShade,
                quantity: selectedQuantity
            }
            this.props.addCartItem(item)
        } else {
            console.log('you need to select product attributes')
        }
    }
  

Мое состояние Redux после добавления элемента

 cart: {
    '1': {
      id: 1,
      sku: '7620896024640',
      size: {
        id: 2,
        name: 'Medium',
        prefix: 'M'
      },
      shade: {
        id: 3,
        name: 'Blue',
        prefix: 'Blue',
        color: 'blue'
      },
      quantity: 3
    },
    '9': {
      id: 9,
      sku: '9125620808537',
      size: {
        id: 2,
        name: 'Medium',
        prefix: 'M'
      },
      shade: {
        id: 1,
        name: 'Red',
        prefix: 'Red',
        color: 'red'
      },
      quantity: 1
    },
    items: {
      '1': {
        id: 1,
        sku: '7620896024640',
        size: {
          id: 2,
          name: 'Medium',
          prefix: 'M'
        },
        shade: {
          id: 3,
          name: 'Blue',
          prefix: 'Blue',
          color: 'blue'
        },
        quantity: 3
      },
      '9': {
        id: 9,
        sku: '9125620808537',
        size: {
          id: 2,
          name: 'Medium',
          prefix: 'M'
        },
        shade: {
          id: 1,
          name: 'Red',
          prefix: 'Red',
          color: 'red'
        },
        quantity: 1
      }
    }
  }
  

Ответ №1:

Я думаю, что вы неправильно устанавливаете состояние в своем редукторе. Можете ли вы попробовать заменить его этим:

 export default (state = INITIAL_STATE, action) => {
    switch (action.type) {
    case actionTypes.ADD_CART_ITEM:
        return { ...state, items: {...state.items, [action.payload.id]: action.payload }}
    default:
        return state
    }
}
  

Комментарии:

1. return { ...state, items: {...state.items, { [action.payload.id]: action.payload }}} выдает синтаксическую ошибку, но return { ...state, items: [...state.items, { [action.payload.id]: action.payload }]} работает, но по-прежнему не является решением, которое я хочу. Он создает массив внутри элементов, а затем добавляет элемент. Итак, это выглядит как firstitem: cart[items][0] [1], seconditem cart[items][1] [1]

2. О, извините. Я думаю [action.payload.id]: action.payload , что не следует заключать в фигурные скобки. Я обновил ответ. Можете ли вы попробовать это, пожалуйста?

3. Одно небольшое предостережение. items обрабатывается как объект, и мне не удается выполнить итерацию по нему с помощью .map. Есть ли простой способ обработать cart.items как массив?

4. Итак, какая структура вам нужна в items ? Это массив объектов?

Ответ №2:

Элементы управления, которые вы не вызываете 2 раза одно и то же действие (например, в других компонентах) или если вы используете эффекты, видят, что вы вызываете правильные действия

Комментарии:

1. Я не понимаю?

2. Если вы говорите, что, возможно, выполняете дополнительные действия, я этого не делаю. Срабатывает только один актон добавления в корзину. Я исправляю ошибки с помощью инструментов отладки redux в Chrome

3. вы используете эффекты??

4. Нет, я использую только классы. useEffects не работает в компонентах класса

5. убедитесь, что в редукторе вы не вызываете одно и то же действие, или я действительно не знаю, почему