Edgar John
Edgar John

Reputation: 45

Transfer objects between two states in React

I'm creating a shopping cart with react hooks that looks like this

const ShoppingCart = () => {
    const [products, setProducts] = useState([
        {id: 1, name: 'Product 1', price: 2500},
        {id: 2, name: 'Product 2', price: 2000},
        {id: 3, name: 'Product 3', price: 2500},
    ])

    const [cart, setCart] = useState()


    const addToCart = (item) => (
        setCart([cart, {item}])
        // setCart([...cart, {item}])
        // setCart([{item}])
    )

    return (
              {
                    products.map((product, i) => (
                        <>
                        <Product name={product.name} price={product.price} key={product.id} />
                        <button 
                            value='Add to cart' 
                            // onClick={((product) => setCart(...cart, product))}
                            onClick={(product) => addToCart(product)}
                            // onClick={console.log(i)}
                            />
                            {console.log(cart)}
                        </>
                    ))
                }
    )
}

The lines commented out are some of the things I had tried that didn't work. Also tried it without the second arg[i] in the lamda function within map.

I'm trying to add a product to the cart object after a user clicks the button

The expected state of cart for example if the user clicks the button next to the product with id of one would be

[{id: 1, name:'Product 1', price: 2500}]

If it would be possible, I would also like to add another field to the object which would be amount

Upvotes: 1

Views: 598

Answers (3)

Taki
Taki

Reputation: 17654

Set the initial value of the cart

const [cart, setCart] = useState([]); // [] is the initial value of the cart

remove product from the callback passed to onClick because it's not the product, it's the click event

<button value="Add to cart" onClick={() => addToCart(product)} />

and the spread operator should work fine

const addToCart = item => {
    setCart([...cart, item]);
};

EDIT

if you want to add the item only once, check if it exists in the cart first :

const addToCart = item => {
  const ndx = cart.findIndex(e => e.id === item.id);
  if (ndx === -1) {
    setCart([...cart, item]);
  }
};

Upvotes: 2

user11385046
user11385046

Reputation:

please use ...cart in your addToCart function because cart would be previous data array and when you do like that [...cart,item] then Previous array would merge in new array and will add new product object in that new array.

 const addToCart = (item) => (
    setCart([...cart,item])
)

and please don't pass param to your click callback function because you are getting this product from above not from click function .use anonymous function like this

 onClick={() => addToCart(product)}

Upvotes: 2

Manjot Singh
Manjot Singh

Reputation: 304

use onClick={((product) => setCart([...cart, product]))}

Upvotes: 0

Related Questions