Setting state returns returns undefined, I don't know why. React

Hello everyone, I am trying to create an add to cart function that takes a product from a page and adds the properties to an array.
My function looks like this

addToCart({ title, desc, price, image }) {
    // This is what is returning undefined 
    this.setState((state) => ({
      cart: [
        ...this.state.cart,
        
        {
          title,
          desc,
          price,
          image,
        },
        console.log(this.state.cart)
      ],
      
    }));
  }

and my items look like:

<Card key={title}  style={{ width: '18rem'}}>
  <Card.Img variant="top" src={imageUrl}width='10rem' height='180rem' />
  <Card.Body>
    <Card.Title>{title}</Card.Title>
    <Card.Text>
      {desc} <br />
      {price}
    </Card.Text>
    <Button variant="primary" onClick={e => this.handleAddToCart(e, this.state.items)} >Add to cart</Button>
  </Card.Body>
</Card>

I am stumped as to why it is putting an array that looks like this

0:
desc: undefined
image: undefined
price: undefined
title: undefined

And also putting two of them for every click.
Here is my full code on codesandbox:


Thank you in advance for your help.

Hello there,

Just the first thing I notice:

this.setState((state) => ({
      cart: [
        ...this.state.cart,
        
        {
          title,
          desc,
          price,
          image,
        },
        console.log(this.state.cart)
      ],
      
    }));

A console.log() passed as an object to cart… this spells trouble.

1 Like

I think that is why it is adding the item twice. I added this trying to figure out why the object was returning undefined. I’ll go ahead and remove that now, that’s one problem fixed!
P.S. Where would I put the console.log() if I wanted it to fire every time the function fired, but not be put inside the cart?

Sure.

An important thing to know about this.setState is that it basically acts as an asynchronous function. So, you could place the log somewhere within addToCart, but this does not ensure you will be shown the updated this.state.cart. So, you might want to add the log within the render method of the component, to see it each time the component updates.

Also, you should probably use the following, since you are not making use of the state object passed to the callback.:

this.setState({
      cart: [
        ...this.state.cart,
        {
          title,
          desc,
          price,
          image,
        }
      ]

Hope this helps.

1 Like

So my second issue is fixed, and I put the console.log() in the right place. Thank you for that!
So I removed the “this.state.items” onClick={e => this.handleAddToCart(e, this.state.items) from this and it gave me a useful error message.
"
TypeError: Cannot destructure property ‘title’ of ‘undefined’ as it is undefined.
"
I am still stuck though as to why the function is not grabbing the data it is suppose to though.

So to prevent anyone from wasting time solving this, the problem was the handleAddtoCart

onClick={e => this.handleAddToCart(e, { title, image : imageUrl, desc, price })}

This is working code. Turns out I wrote the function there incorrectly.