小编典典

在React中的html输入中在美分和美元之间转换

reactjs

我的状况有点怪异,我在我们的app中处理货币。在模型方面,由于不希望在服务器端处理小数点,因此在发送到服务器之前,我将货币保存为美分。但是,在视图中,我要显示的是正常货币而不是美分。

因此,我有一个输入字段,在这里我从美元中获取数据并将其更改为美分:

<input name="balance" type="number" step="0.01" min="0" placeholder="Balance in cents" onChange={this.handleUpdate} value={this.props.user.balance / 100)} />

当输入值发生变化时,我将其改回美分,然后再将其发送到上游:

handleUpdate: function(e) {

  var value = e.target.value;

  // changing it back from cents to dollars  
  value = parseFloat(value) * 100;

  // save back to the parent component managing the prop
  this.props.onUserUpdate(value);

}

这使我陷入僵局,我无法输入小数点“”。让我示范一下:

  1. 33在输入框中->变为3300父状态->返回33组件prop中的- 一切正常

  2. 33.3在输入框中->变为3330父状态->返回33.3组件prop中的状态- 一切正常

  3. 33.在输入框中->变为3300父状态->返回33组件prop中的状态- 这就是问题所在

如案例3所示,用户首次输入“”。这不会转换回与“”相同的数字。

由于它是受控输入,因此基本上没有写“。”的方法。

我尝试将不受控制的元素与结合使用defaultValue,但是在呈现组件时,数量prop尚未准备好,因此它只是空的

http://jsfiddle.net/fpbhu1hs/


阅读 315

收藏
2020-07-22

共1个答案

小编典典

使用派生值的受控输入可能会比较棘手-如果您需要能够显示无效或其他怪异的输入,那么…

  1. 始终将输入保持value在其组件本身中state

    <input value={this.state.value} onChange={this.handleUpdate} // rest as above...
    
  2. 得出初步valuegetInitialState()

        getInitialState: function() {
      return {value: this.props.user.balance / 100}
    }
  1. 实现componentWillReceiveProps(nextProps)检测道具的值何时从上方改变并重新推导状态值
        componentWillReceiveProps: function(nextProps) {
      if (this.props.user.balance != nextProps.user.balance) {
        this.setState({value: nextProps.user.balance / 100})
      }
    }

现在,当用户输入“ 33.”时,您可以使用来存储其文字输入setState(),然后回调到父级。

    handleUpdate: function(e) {
      var value = e.target.value
      this.setState({value: value})
      this.props.onUserUpdate(parseFloat(value) * 100)
    }

如果父母通过道具传回给孩子的值没有改变(3300 == 3300在这种情况下),则componentWillReceiveProps()不会做任何事情。

工作片段:

    <script src="http://fb.me/react-with-addons-0.12.2.js"></script>

    <script src="http://fb.me/JSXTransformer-0.12.2.js"></script>

    <div id="example"></div>

    <script type="text/jsx;harmony=true">void function() { 'use strict';



    var Parent = React.createClass({

      getInitialState() {

        return {cents: 3300}

      },



      _changeValue() {

        this.setState({cents: Math.round(Math.random() * 2000 + Math.random() * 2000)})

      },



      _onCentsChange(cents) {

        this.setState({cents})

      },



      render() {

        return <div>

          <p><strong>Cents:</strong> {this.state.cents.toFixed(0)} <input type="button" onClick={this._changeValue} value="Change"/></p>

          <Child cents={this.state.cents} onCentsChange={this._onCentsChange}/>

        </div>

      }

    })



    var Child = React.createClass({

      getInitialState() {

        return {dollars: this.props.cents / 100}

      },



      componentWillReceiveProps(nextProps) {

        if (this.props.cents != nextProps.cents) {

          this.setState({dollars: nextProps.cents / 100})

        }

      },



      _onChange(e) {

        var dollars = e.target.value

        this.setState({dollars})

        if (!isNaN(parseFloat(dollars)) && isFinite(dollars)) {

          this.props.onCentsChange(parseFloat(dollars) * 100)

        }

      },



      render() {

        return <div>

          <input type="number" step="0.01" min="0" value={this.state.dollars} onChange={this._onChange}/>

        </div>

      }

    })



    React.render(<Parent/>, document.querySelector('#example'))



    }()</script>
2020-07-22