Search code examples
javascriptreactjstypescriptreact-nativesetstate

React Typescript - set two values into state


I have a form with 3 number fields. The user can enter a quantity and unit price. Which will then show the total price in the last field as a disabled field.

My current code sets the value correctly in the Total Price input field, however it fails to set the state.

So for example if the user inputs Quantity equal to 4 and UnitPrice to 25. this.state.TotalPrice should be 100

handleChangeQuantity(event) {
    const { value } = event.target;
    this.setState({ Quantity: value }); 
}   

handleChangeUnitPrice(event) {
    const { value } = event.target;
    this.setState({ UnitPrice: value }); 
}

handleChangeTotalPrice(event) {
    const { TotalPrice } = event.target.value;
    this.setState({ 
        TotalPrice: this.state.Quantity * this.state.UnitPrice
    }); 
}   


<div>
    <label>
        Quantity
    </label>
    <input
        value={this.state.Quantity}
        onChange={this.handleChangeQuantity}
        type="number"
        className="phone validate"
        name="Quantity #1"
        maxLength={9}
        pattern='[0-9]{0,5}'
    />
</div>

<div>
    <label>
        Unit Price
    </label>
    <input
        value={this.state.UnitPrice}
        onChange={this.handleChangeUnitPrice}
        type="number"
        className="phone validate"
        name="Unit Price #1"
        maxLength={15}
        pattern='[0-9]{0,5}'
    />
</div>

<div>
    <label>
        Total Price
    </label>
    <input
        value={this.state.Quantity * this.state.UnitPrice}
        onChange={this.handleChangeExtendedPrice}
        type="number"
        className="phone validate"
        name="Estimated Extended Price #1"
        disabled
    />
</div>

Solution

  • In the last input field totalPrice , you could set the value as,

    value={this.state.TotalPrice}
    

    So you can set the state value in,

    handleChangeTotalPrice = () => {
        this.setState({
          TotalPrice: this.state.Quantity * this.state.UnitPrice,
        })
        console.log(this.state.TotalPrice)
      }
    

    So you can call the handleChangeTotalPrice function whenever there is a change in quantity and price..

    The state value of TotalPrice would gets updated accordingly.

    You could change your code like the following,

    import React from 'react'
    
    export class App extends React.Component {
      state = {
        Quantity: 0,
        UnitPrice: 0,
        TotalPrice: 0,
      }
    
      handleChangeQuantity = async (event: any) => {
        const { value } = event.target
        await this.setState({ Quantity: value })
        this.handleChangeTotalPrice()
      }
    
      handleChangeUnitPrice = async (event: any) => {
        const { value } = event.target
        await this.setState({ UnitPrice: value })
        this.handleChangeTotalPrice()
      }
    
      handleChangeTotalPrice = () => {
        this.setState({
          TotalPrice: this.state.Quantity * this.state.UnitPrice,
        })
        console.log(this.state.TotalPrice)
      }
    
      render() {
        return (
          <div>
            <div>
              <label>Quantity</label>
              <input
                value={this.state.Quantity}
                onChange={this.handleChangeQuantity}
                type="number"
                className="phone validate"
                name="Quantity #1"
                maxLength={9}
                pattern="[0-9]{0,5}"
              />
            </div>
    
            <div>
              <label>Unit Price</label>
              <input
                value={this.state.UnitPrice}
                onChange={this.handleChangeUnitPrice}
                type="number"
                className="phone validate"
                name="Unit Price #1"
                maxLength={15}
                pattern="[0-9]{0,5}"
              />
            </div>
    
            <div>
              <label>Total Price</label>
              <input
                value={this.state.TotalPrice}
                type="number"
                className="phone validate"
                name="Estimated Extended Price #1"
                disabled
              />
            </div>
          </div>
        )
      }
    }
    

    Working Sandbox