React: Getting a weird output when trying to add a number to an input value

React: Getting a weird output when trying to add a number to an input value
0

#1

Hi there. I’m attempting to build a simple React app that adds 37 to a number provided by the user, then displays it. The number is provided in one of two ways: via a counter they click on x number of times, or a value the user just simply types into an input box. In the former case, everything is working fine. However, in the case of the number typed in the input, something odd is happening. For example, if I type 5, the output is 537 rather than 42.

class ButtonsNInput extends React.Component{
  constructor (props){
    super (props)
    this.state = {
      count: 0,
      inputVisibility: true,
      buttonsVisibility: true,
    }
    this.addChirp = this.addChirp.bind(this);
    this.subtractChirp = this.subtractChirp.bind(this);
    this.handleChange = this.handleChange.bind(this);
    }
     
    addChirp = () => {
      this.setState({
        count : this.state.count + 1,
        inputVisibility: false,
      })}
    
    subtractChirp = () => {
      this.setState({
        count : this.state.count - 1,
        inputVisibility: false
      })}  
      
    handleChange = (event) => {
      this.setState({
        count: event.target.value,
        buttonsVisibility: false
      })} 


    render () {
    return (
      <div>
    {this.state.buttonsVisibility ? <div><button onClick={this.addChirp}>Add a Chirp</button><button onClick={this.subtractChirp}>Subtract a Chirp</button></div> : <br/>}
        <h1>{this.state.count}</h1>
        {this.state.inputVisibility  ? <div><input onChange={this.handleChange}></input> </div>: null}
        <br/>
        <Submit count={this.state.count}/>
      </div>
    )
  }
}


class Submit extends React.Component {
 constructor (props) {
   super(props)
   this.state ={
      SubmitClicked : false,
   }
 this.handleClick1 = this.handleClick1.bind(this);
   
 }
  
 
   handleClick1 = () => {
      this.setState({
         SubmitClicked: true,
       })}
   
  render (){
    return(
      <div>
        <button onClick={this.handleClick1}>Submit</button>
        {this.state.SubmitClicked ? <div> <p>It's {this.props.count + 37}°F outside!</p> <br/></div> : null}
        </div>)
        
}
      }

Here’s the codepen, it’s got some extra fluff, but the bones are the same:

I’m not certain, but I think it’s got something to do with using event.target.value to update the state of count. Can anyone point me in the right direction?


#2

I’ve edited your post for readability. When you enter a code block into a forum post, please precede it with a separate line of three backticks and follow it with a separate line of three backticks to make easier to read.

Note: Backticks are not single quotes.

See this post to find the backtick on your keyboard. The “preformatted text” tool in the editor (</>) will also add backticks around text.


#3

When I type 5, the output is 51. I see zero code which is trying to add the number 37 to the value of the input. I do see in the following handleChange function which sets the count property to event.target.value (which is a string). You need to convert it to a Number.

  handleChange = event => {
    this.setState({
      count: event.target.value,
      buttonsVisibility: false
    });
  };

Once you do that, it still will not add 37 to count, but it will display the value + 1 based on the following line:

<p>It's {this.props.count + 1}°F outside!</p> <br />

#4

Thanks for taking the time to respond!I changed it to 1 in a last ditch debugging attempt before posting here, but I must’ve goofed and forgot to change that back to 37.

I did a little googling, and it looks like you were trying to point me in the parseInt direction. I appreciate you not just giving me the answer outright, and this definitely solves my issue. Just for future reference, is there a way to set the value to the submitted number straight away rather than converting the string to a number?


#5

Well, since event.target.value is always going to be a string, you have no choice but to make the conversion either in the handleChange function or in the render. I think it is best done in the handleChange, that way state.count always has a number and you do not have to convert it anywhere else you may want to reference count.

FYI - There are multiple ways of making the conversion.

parseInt(event.target.value)

OR

Number(event.target.value)

OR

+event.target.value // this coerces the string into a number

#6

Interesting. But if event.target.value is always a string, then why do the addChirp and subtractChirp methods work? I haven’t done any special conversions there, and followed a similar strategy to what is used in the “Build a Simple Counter” React challenge.


#7

Because addChrip and subtractChirp never reference event.target.value. They only reference this.state.count and this.state.count starts at 0 (a number and not a string).


#8

That makes sense. Thanks again for all your help!