Claim
Claim

Reputation: 921

React: Adding an object to an array in state through input fields

So, I want to read two text field values and use a button to reset my state. Here's my code:

this.state = {

  items: [{
    name: 'Cola',
    price: 1.20
  }, {
    name: 'Stuff',
    price: 0.50
  }, {
    name: 'Beer',
    price: 0
  }
]
};


handle = (name, price) => {
    this.addProductToBasket(name, price);
  }

addProductToBasket = (name, price) => {

    var newArray = this.state.items.slice();

    var itemToBeAdded = {
      name : name,
      price : price
    }; 

    newArray.push(itemToBeAdded);
    console.log(newArray)

    this.setState( {items:newArray} )

}


<form onSubmit={ () => this.handle(this.state.items.name, this.state.items.price)}>
  <input type="text" name='name' value={this.state.items.name}/>
  <input type="text" name='price' value={this.state.items.price}/>
  <button type="submit" value="Submit">BUTTON</button>
</form>

I tested

addProductToBasket

and it works! I debugged the code in Chrome and I just get undefined for name and price.

Upvotes: 1

Views: 7260

Answers (3)

A.K.47
A.K.47

Reputation: 237

As @sketchedin pointed out, the parameters passed are not the value entered by user itself but instead are bound to the state object.

In order to pass the parameters you either have to call an onChange() function but instead if you want to call it from the handle function of form you should make sure that you capture the current input values(i.e. the params passed should be bound to the input and not the state object).

handleSubmit(event) {
  event.preventDefault();
  const form = event.target;
  const data = new FormData(form);

  const name = form.elements[name];
  const price = form.elements[price];

  this.addProductToBasket(name, price);
}

What we are doing in the above lines is that we are using DOM api's form element and fetching the correct input values instead of using REACT to manipulate the forms.

Upvotes: 0

Andy
Andy

Reputation: 63524

First change your state to include name and price:

this.state = {
  name: '',
  price: '',
  items: [...]
}

You want to add a new function that handles changes in your input fields. Call it handleInput. It takes the event, grabs the name of the input, and sets the appropriate state value of that key.

handleInput(e) {
  let { name, value } = e.target;
  if (name === 'price') value = +value;
  this.setState({ [name]: value });
}

Here's the corresponding JSX:

 <input type="text" name="name" onChange={this.handleInput} value={this.state.name} />
 <input type="text" name="price" onChange={this.handleInput} value={this.state.price} />

And here's a working demo. Look at the console for the changes to this.state.

Upvotes: 2

sketchedin
sketchedin

Reputation: 262

The parameters passed to the handle function are incorrect. They are currently referring to the array of items in state, but it should be referring to the input field values.

Create something like this.state.input.name and this.state.input.price. These would have to be set by text field onChange handlers.

Upvotes: 0

Related Questions