0

The following code example works well with text input type, but allows inputs like 012 or 0012 to be entered when using the number input type.

The console.log line always runs and shows the right value, and the App state is also correct when checked with React Developer Tools. It's only that the controlled input is not being "controlled" somehow.

Why is this happening, and what is the recommended way to use number inputs with React?

class App extends Component {
  constructor() {
    super()
    this.state = {
      value: '',
    }
  }

  handleChange = e => {
    const value = e.target.value
    const num = parseInt(value, 10)
    console.log(num)
    this.setState({ value: isNaN(num) ? '' : num })
  }

  render() {
    return (
      <div className="App">
        <input type="number" value={this.state.value} onChange={this.handleChange} />
      </div>
    )
  }
}
8
  • 0012 is a number. Commented Aug 25, 2017 at 10:33
  • Not after parseInt(...., 10) Commented Aug 25, 2017 at 10:35
  • i think it's working as you are expecting, check this fiddle Commented Aug 25, 2017 at 10:38
  • @MayankShukla then it's probably something with the React version. I'm using the latest create-react-app (React 15.6.1, Chrome 60 on OS X). Commented Aug 25, 2017 at 10:43
  • not sure about that, but i think it should not depent on react version. Commented Aug 25, 2017 at 10:48

1 Answer 1

1

So, you bind the model of the controlled input to a number in your state, which is not being changed between 012 and 12 - so it leaves it as is.

instead, you can do

render() {
  const value = this.state.value.toString()
  return <input type="number" value={value} onChange={this.handleChange} />
}

the string will actually differ and it will re-render properly, stripping the leading 0. or, you could setState({ value: String(num) })

Sign up to request clarification or add additional context in comments.

3 Comments

No the value should change between 01 -> 012. Same way as it should change between 0 -> 01. Yet it's not being updated.
It should change without .toString(), I believe.
I'll grant you that it is kind of strange but I'd argue binding non primitive values to inputs is not a good pattern anyway when the browser will serialise it and call the toString internally. If you change the type from number to text, it works as expected (but does not wash input). So, it may be a particular browser implementation around input[type=number]. Either way, this QnA site is about getting your code to work--which this does--not discussing what changes react devs need to make - that's for the GH issues.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.