Number input is string not integer in React

Viewed 25154

I have a react component. Im passing the updateInventory function down from my top level component.

class Inventory extends Component {
  constructor(props) {
    super(props);
    this.state = {
      name: this.props.name,
      price: this.props.price,
      id: this.props.id
    };
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(e) {
    this.setState({
      [e.target.name]: e.target.value
    });
  }

  render(props) {
    return (
      <form onSubmit={(e)=>this.props.updateInventory(e, this.state)}>
        <input name='name' value={this.state.name} onChange={this.handleChange} />
        <input name='price' type='number' value={this.state.price} onChange={this.handleChange} />
        <button type='submit'>Update</button>
      </form>
    )
  }
};

export default Inventory;

In my top level component:

updateInventory = (e, state) => {
  let pizzaState = this.state.pizzas;
  const index = pizzaState.findIndex((pizza)=>{
    return pizza.id === state.id;
  });
  Object.assign(pizzaState[index], state);
  console.log( pizzaState );
  e.preventDefault();
};

This appears to be working so far (I havn't updated my top level state yet) but I can see that when I update the price the new value is a string not an integer. I was hoping to just have the one handleChange function for all my inputs as ill be adding some more, is this possible?

3 Answers

You can check the type and name of the target and handle the value accordingly.

For Example

this.setState({
  [e.target.name]: e.target.type === 'number' ? parseInt(e.target.value) : e.target.value
});

// or

this.setState({
  [e.target.name]: e.target.name === 'price' ? parseFloat(e.target.value) : e.target.value
});

You can use valueAsNumber property of the Input element

For example:

handleChange(e) {
    this.setState({
        [e.target.name]: e.target.valueAsNumber || e.target.value
    });
}

The e.target.valueAsNumber will give you the value as number or NaN if the input is empty.

The || e.target.value is a fallback in case the valueAsNumber is NaN.

The parseFloat in onChange wont work since 4. will be parsed as 4 and the user wont be able to type any new digits. Check react-input-number for numeric input in react.

Related