I have a simple onChange which takes the user's input pareses it and sets the state to render. Here is the code.
import React, { Component } from 'react';
import './App.css';
class App extends Component {
constructor() {
super();
this.state = {
random: {
foo: 0
}
}
}
onChange(e) {
let random = this.state.random;
random[e.target.name] = parseFloat(e.target.value);
this.setState({random});
}
render() {
return (
<div className="App">
<input onChange={this.onChange.bind(this)} type="text" name="foo" value={this.state.random.foo} />
</div>
);
}
}
export default App;
What I don't understand is where my decimal is going. I know there is no validation in place to stop the user from entering letters, but this is just a sample app to test this issue I ran into. When I enter a decimal point in does not get rendered. Where am I going wrong?
The problem is that React's onChange
doesn't behave like the browser's onChange
It behaves like onInput
So it is getting called every time you type a value. This results in your parseFloat
actually parsing 1.
instead of 1.2
and the parsed value of 1.
is 1
As other have said, the problem is that the number type doesn't hold enough information about the state of the input, so when 1.
makes a round trip it loses the .
.
In other words, an input is a widget for editing a string, and your state doesn't contain enough information to recreate that string correctly, and instead the decimal point gets lost.
Thus, one solution is to store it as a string in your state, perhaps called inputValue
. Then, using unidirectional data flow, manage the translation between that string and the parts of code that think of it numerically very explicitly. Converting from a string to a number is dangerous -- not every string represents a number, so that part of the code needs to deal with validation (and not lose track of the text input). And converting from a number to a string is risky, as you've already observed, so it should only be done when there is a good reason (for instance, the server is pushing an event that the data changed somewhere else, swap it out).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With