Demo: jsfiddle
/**
* @jsx React.DOM
*/
var NumberField = React.createClass({
render: function() {
return <input type="number" value={this.props.value} onInput={this.onInput}/>;
},
onInput: function(e) {
if (!this.props.onValueChange) {
return;
}
var value = parseInt(e.target.value, 10);
return this.props.onValueChange(value);
}
});
var TempConverter = React.createClass({
getInitialState: function() {
return {c: 0};
},
render: function() {
var c = this.state.c;
return <p>
<NumberField onValueChange={this.onChangeC} value={c}/> C
<br/>
<NumberField onValueChange={this.onChangeF} value={c2f(c)}/> F
</p>;
},
onChangeC: function(c) {
this.setState({c: c});
},
onChangeF: function(f) {
this.setState({c: f2c(f)});
}
});
function c2f(c) {
return 1.8 * c + 32;
}
function f2c(f) {
return 0.5555555555555 * (f - 32);
}
When I change the °F value by one, it gets converted to Celsius and then back to Fahrenheit, resulting in rounding errors.
Is there any way to avoid updates on the currently modified element?
Backbone.js has the exact same problem.
You ask,
Is there any way to avoid updates on the currently modified element?
In general, not really. This is actually a feature of React: your UI is guaranteed to always be in sync with your underlying data! Of course, by overriding shouldComponentUpdate
and doing some manual work you can prevent the fields from changing, but it's intentional that the path of least resistance leads you to an always-accurate UI.
It sounds like you want to be able to show either an exact °C temperature or an exact °F temperature, so the best approach here seems to be to store that as well. Otherwise, you're feigning more precision than you actually have. I've modified your code so that it operates in one of two modes: Celsius mode or Fahrenheit mode:
var TempConverter = React.createClass({
getInitialState: function() {
return {type: "c", val: 0};
},
render: function() {
var c, f;
if (this.state.type === "c") {
c = this.state.val;
f = c2f(c);
} else {
f = this.state.val;
c = f2c(f);
}
Tracking the value this way allows you to store and display the exact temperature the user entered and be confident that you're not losing any precision.
Live demo here: jsfiddle
(You could also round the temperature before displaying, of course, but your response to your Backbone.js question indicates that's not your preferred solution.)
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