Search code examples
reactjscart

React - Deleting from array messes up component state


I'm making a shopping cart and if I add for example 1 small pizza, 2 medium pizzas, 3 large pizzas, and 4 x-large pizzas to the cart, and then I remove the 2 medium pizzas, then the quantity of the 4 x-large pizzas changes to 3 and the quantity of the large pizzas changes to 2. The quantity of the small pizza remains at 1. I just want to remove the item without affecting the quantites of the other items. Please help me fix this code:

import React, { useEffect, useState, useContext } from 'react';
import { CartContext } from './App'
import QuantitySelector from './QuantitySelector';
import CartItem from './CartItem';

export default function Cart(props) {
    const [cart, setCart] = useContext(CartContext);
    return (
        <div>
        {
            cart.map((cartItem, key) =>
                <div>{key}
                    <CartItem
                        key={key}
                        cid={key}
                        cartItem={cartItem}
                        quantity={cartItem.quantity} />
                </div>
            )
        }
        </div>
    );
}


import React, { useEffect, useState, useContext } from 'react';
import { CartContext } from './App'
import QuantitySelector from './QuantitySelector';

export default function CartItem(props) {
    const [cart, setCart] = useContext(CartContext);
    const cartItem = props.cartItem;
    const cid = props.cid;
    const [quantity, setQuantity] = useState(props.quantity);
    function removeFromCart(e, cid) {
        setCart(cart.filter(function (cartItem, k) {
            console.log("k = " + k);
            return k !== cid;
        }));
    }
    return (
        <div className="m-1">
            <h5>{cartItem.name} (x {quantity})</h5>
            <span>{cartItem.val1 == 1 ? cartItem.size1 : ""}</span>
            <span>{cartItem.val2 == 1 ? cartItem.size2 : ""}</span>
            <span>{cartItem.val3 == 1 ? cartItem.size3 : ""}</span>
            <span>{cartItem.val4 == 1 ? cartItem.size4 : ""}</span>
            <div className="row">
                <div className="col-xs-6 col-sm-6">
                    <QuantitySelector
                        inputValue={quantity}
                        onInputValueChange={setQuantity} />
                </div>
                <div className="col-xs-6 col-sm-6">
                    <button
                        className="btn btn-primary btn-sm"
                        onClick={(e) => removeFromCart(e, cid)}>Remove</button>
                </div>
            </div>
        </div>
    )
}

I made sure that the correct indexes are being removed from the array.


Solution

  • The issue here is that you are updating the entire cart when removing an item, which is causing the quantities of other items to change. Instead of filtering the cart array directly, you should create a new array with the items you want to keep. This way, the original array remains unchanged, and you won't inadvertently affect the quantities of other items.

    export default function CartItem(props) {
    const [cart, setCart] = useContext(CartContext);
    const cartItem = props.cartItem;
    const cid = props.cid;
    const [quantity, setQuantity] = useState(props.quantity);
    
    function removeFromCart(e, cid) {
        // Create a new array without the item to be removed
        const newCart = cart.filter(function (cartItem, k) {
            return k !== cid;
        });
    
        // Update the cart with the new array
        setCart(newCart);
    }
    
    return (
        // ... rest of the component remains unchanged
    );
    

    }