I want a list of text inputs that are in sync with a list of values I have in the backend. So typing into them updates the values, and updates to the values reflect in the text inputs.
This is a typical 2-way binding situation with something like this:
class BoundInput extends Component {
constructor(props) {
super(props);
this.state = {textVal: ''};
}
handleChange = evt => this.setState({textVal: evt.target.value});
render() {
return <input type="text"
value={this.state.textVal}
onChange={this.handleChange} />
}
}
But I would like to store the value not as exactly what the user typed but, say, a conversion from cm. to in.
Unfortunately, the conversion and then conversion back is not quite perfect.
E.g. typing '2.'
immediately gets converted back to '2'
, so you get stuck if you want to type a decimal and anything beyond.
I'd like to be able to have the stored value update the input display unless the input is active, in which case it should only be updating the stored value from the input.
So I have a Boolean that lets me conditionally pass in value
to the text input, so the typer can type unhindered, and the display may update to an equivalent representation only once they leave focus (e.g. '1.'
suddenly becomes '1'
or '1.0'
), which is fine.
I tried this but I get the error that an input component must be either controlled, or uncontrolled, for its whole lifetime. No switching it up like I did.
Any suggestions on overall strategy, or getting around this particular warning about controlled vs. uncontrolled?
Perhaps a way to kill and re-mount the input component before switching from passing value
to not passing value
?
Something I did which is ugly as all heck is just duplicate my input component (which I call NiceInput
), and when it is not active I swap in the duplicate NiceInput2
. This works, but there has to be a less ridiculous way than duplicating components :D