10

双转换问题

演示: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);
}

当我将 °F 值更改为 1 时,它会转换为摄氏温度,然后再转换回华氏温度,从而导致舍入误差。

有什么办法可以避免对当前修改的元素进行更新?

回击

Backbone.js 有完全相同的问题

4

1 回答 1

13

你问,

有什么办法可以避免对当前修改的元素进行更新?

一般来说,不是真的。这实际上是 React 的一个特性:保证您的 UI 始终与您的底层数据同步!当然,通过重写shouldComponentUpdate和做一些手动工作,您可以防止字段发生变化,但有意使阻力最小的路径引导您获得始终准确的 UI。

听起来您希望能够显示精确的°C 温度或精确的°F 温度,因此这里最好的方法似乎也是存储它。否则,你假装比你实际拥有的更精确。我已经修改了您的代码,使其以两种模式之一运行:摄氏模式或华氏模式:

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);
        }

通过这种方式跟踪值,您可以存储和显示用户输入的确切温度,并确信您不会丢失任何精度。

现场演示:jsfiddle

(当然,您也可以在显示之前对温度进行四舍五入,但您对 Backbone.js 问题的回答表明这不是您的首选解决方案。)

于 2013-12-27T07:18:07.283 回答