Home > Enterprise >  removing single same item from cart removes all items
removing single same item from cart removes all items

Time:10-01

Below is my code for react sample project:

    import Products from "./components/Products";
    import Cart from "./components/Cart";
    import { useState } from "react";
    import './App.css';
    function App() {
      const [page, setPage] = useState("Products");
      const [cart, setCart] = useState([])
      const switchPages = (nextPage)=> {
        setPage(nextPage)
      }
      const addCart =(p) =>{
        console.log("{...p}", {...p});
        console.log("p", p);
        setCart([...cart, {...p}])
      }
      const removeCart = (p)=> {
        console.log(p);
        setCart(cart.filter(i => i !== p))
      }
      return (
        <div className="App">
         <button onClick={() => switchPages("Products")}>View Products</button>
         <button onClick={() => switchPages("Cart")}>View Cart {cart.length}</button>
         {page === "Products" && <Products addCart={addCart}/>}
         {page === "Cart" && <Cart cartItems={cart} removeCart={removeCart}/>}
        </div>
      );
    }
    
    export default App;




Below is the code for Products.js

import React, { useState } from 'react'

const Products = ({addCart}) => {
    const [products] = useState([
        {
            name: "iPhone",
            price: 80000
        },
        {
            name: "Laptop",
            price: 55500
        },
        {
            name: "iPad",
            price: 45000
        }
    ])

    return (
        <div>
            {
              products.map((product, idx) => {
                  return (
                      <div className="box" key={idx}>
                          <h1 className="small">{product.name}</h1>
                          <p>Price: {product.price}</p>
                          <button onClick={()=> addCart(product)}>Add to cart</button>
                      </div>
                  )
              })  
            }
        </div>
    )
}

export default Products

As you can see, while setting the cart in addCart function I am using {...p} setCart([...cart, {...p}]), instead of just p setCart([...cart, p]). If I use only p, it removes all items if I try to remove single one and if I use {..p} then it removes the single entry. Can anyone please explain why we have to use {...p} instead of just p

Thanks

CodePudding user response:

The difference between p and {...p} is that the latter copies the object. It seems like you're mixing up references somewhere, but not in the snippet you shared.

CodePudding user response:

now with your code we can tell where the issue is, basically you are passing objects by reference and using that reference to delete an object, so basically when you pass only p you will end up with an array like this

[
  obj1,
  obj2,
  obj3,
  ...
  objN,
]

lets say you clicked many times on the object (lets call it genesis):

{
    name: "iPhone",
    price: 80000
},

basically it seems that all the objects are the same in different parts of memory but what is happening is that all of obj1, obj2, obj3 ... etc are pointing to the genesis object, therefore when you try to use filter with this condition:

cart.filter(i => i !== p)

you are checking obj1 === genesis, obj2 === genesis, ... ,objN === genesis which we know they are all the same:

that is why your filter is deleting all your objects

moving to the { ...p } part, if you understand the previous concept, now you know that using the spread operator will copy your object, therefore when doing the filter, will delete the correct one.

note: it would be much better to filter using some sort of ids so you can control the filtering even better, also I'd rather to add the items to the cart like this:

<button onClick={()=> addCart({...product})}>Add to cart</button>

using the spread operator in here, so you can use only p directly on the other methods.

  • Related