0

I have a customers array in state

state = {
    clearable: true,
    addItem: {
      name: '',
      age: '',
      customers: [{ name: '', total: 0, prices: 0 }]
    }

Now in my function below, i am setting states to the array customer but then, it keeps giving the default values when i console after setting states.

function handleCustomer(event) {
  let customer_details = [...this.state.addItem.customers]
  this.setState({
    price: event.target.value,
    total: event.target.value * event.target.value
  },
    () => {
      customer_details.push({
        name: 'Customer',
        price: this.state.price,
        total: this.state.total,
      })
      this.setState({ customer_details });
    });
}

When i console this array customer, i keep getting the default value. How can i set states the new values for the array customer.

What could i be doing wrong please?

PS: I have had ideas from other solutions but i am not seeing any error in the code above

adiga
  • 34,372
  • 9
  • 61
  • 83
Switzz
  • 69
  • 1
  • 3
  • 8
  • 1
    `this.setState({customer_details});` sets `this.state.customer_details` to `customer_details`, not really what you want, I guess? edit: looking at this again, none of your `setState` calls will work properly. –  Jul 12 '19 at 06:38
  • 1
    @adiga That was my first thought, too, but I don't think that's the problem. See my comment. –  Jul 12 '19 at 06:39
  • @ChrisG OP's pushing another customer object to the local variable `customer_details` and updating the state. But, they are doing it inside the callback of previous `setState` which is probably not a good idea. – adiga Jul 12 '19 at 06:44
  • @ChrisG I thought the `state` has a property called `customer_details`. The indentation confused me. My bad. – adiga Jul 12 '19 at 06:47
  • @adiga That's the one thing that "works", as far as I can tell, because it means that `this.state.price` for instance actually has the expected value already. Still, the main issue is that OP isn't updating existing state but a) pushing data needlessly and b) creating new keys, leaving the original data untouched. –  Jul 12 '19 at 06:48

3 Answers3

0

You should code:

function handleCustomer(event)
{
  const customer_details = [...this.state.addItem.customers],
        price = event.target.value,
        total = price * price
  this.setState({ 
      addItem: { 
         ...this.state.addItem,
         customer_details: [ ...customer_details, {
           name: 'Customer',
           price,
           total,              
        }]
      }
  });
}
Ryan Nghiem
  • 2,417
  • 2
  • 18
  • 28
  • The original state object doesnt appear to have price or total properties though – Chris Ngo Jul 12 '19 at 06:45
  • I downvoted because you're pushing `{ price, total, customer_details }` directly to `state`, which is not what OP wants at all. See my answer. –  Jul 12 '19 at 06:52
0

This has to be rewritten completely, as far as I can tell.
Try this:

function handleCustomer(event) {
  let customers = [...this.state.addItem.customers];
  customers.push({
    name: 'Customer',
    price: event.target.value,
    total: event.target.value * event.target.value
  });
  this.setState({
    addItem: { customers }
  });
}

First, I'm creating a copy of the array. Next, the new element is pushed. I can now update the state by replicating the nesting.

Here's another version using a single statement:

function handleCustomer(event) {
  this.setState({
    addItem: {
      customers: [
        ...this.state.addItem.customers,
        {
          name: "Customer",
          price: event.target.value,
          total: event.target.value * event.target.value
        }
      ]
    }
  });
};
  • This is probably closest to the answer OP is looking for, but I'm a bit confused by what they're asking anyway :/ – Chris Ngo Jul 12 '19 at 06:58
  • @ChristopherNgo It's twofold: how to update an array, and how to update a nested structure. This is also why there's no obvious duplicate I can find. –  Jul 12 '19 at 07:21
0

Apparently, your customer_details is an Array not an Object, passing only the Array does not apply the value to any of the property in your state.

Try

this.setState({addItem:{customers : [...customer_details]}})

It will update the state customers property within addItem with new value

Ethan Vu
  • 2,911
  • 9
  • 25