2
votes

I am using the following reducer to add products, delete them, and add them to a cart. I would like the 'ADD_TO_CART' method when called to add an item to the cart, but if an item is already in the cart, I would like to increase it by 1. However, the method is increasing cart items by 2 instead of 1

export default (state, action) => {
    switch (action.type) {
        case 'ADD_PRODUCT':
            return {
                ...state,
                products: [action.payload, ...state.products]
            }
        case 'DELETE_PRODUCT':
            return {
                ...state,
                products: state.products.filter(product => product.id !== action.payload)
            }
        case 'ADD_TO_CART': if (state.cart.some(cartItem => cartItem.id === action.payload.id)) {
            const updatedItemIndex = state.cart.findIndex(cartItem => cartItem.id === action.payload.id)
            let cartItems = [...state.cart]
            let itemToUpdate = cartItems[updatedItemIndex]
            itemToUpdate.quantity++
            return { ...state, cart: cartItems }

        } else {
            const newItem = { ...action.payload, quantity: 1 }
            return { ...state, cart: [...state.cart, newItem] }
        }
        default:
            return state
    }
}

This is the code dispatching the action

function addToCart(product) {
    dispatch({
        type: 'ADD_TO_CART',
        payload: product
    })
}

I am calling the action from the following component

import React, { useContext } from 'react' import { ProductContext } from './ProductContext'

export const ProductCard = ({ product }) => { const { deleteProduct, addToCart } = useContext(ProductContext)

const handleDelete = () => {
    deleteProduct(product.id)
}

const handleCart = () => {
    addToCart(product)
}


return (
    <div className='product__card'>
        <h3>{product.productName}</h3>
        <p>{product.price}</p>
        <button className='button'>View Product</button>
        <button onClick={handleCart} className='button'>Add to Cart</button>
        <button onClick={handleDelete} className='button'>Delete</button>
    </div>
)

}

3
How are you dispatching the Add to Cart action? - Ajeet Shah
@AjeetShah I am dispatching it from a context provider and calling the function from a component, I have edited the question to include code for both - Alex Masinde

3 Answers

0
votes

Try changing the quantity from a number to an empty quote.

Old: const newItem = { ...action.payload, quantity: 1 }

New: const newItem = { ...action.payload, quantity: '' }
0
votes

You have a mistake. You MUTATE your state.

        let cartItems = [...state.cart] // <-- reinitialize only the array,
        // the array items remains with the same reference!!!!
        let itemToUpdate = cartItems[updatedItemIndex]
        itemToUpdate.quantity++ // <--- this will mutates your state!!!
        return { ...state, cart: cartItems }

Fix: create a new item, and copy the data with the spread operator, and delete the old one.

0
votes

I have ran into the same problem with a very similar situation, and none of the current answers helped me. Therefore I can only recommend

itemToUpdate.quantity++

Be changed into

itemToUpdate.quantity += 0.5;

I know that this is not the correct way to solve this problem, but the functionality works, and you can change it later when you will find the solution