简体   繁体   English

反应组件和无效输入

[英]React Component and Invalid Input

I have the following react component: 我有以下反应组件:

var App = React.createClass({
    getInitialState: function() {
        return {value: 4.5}
    },
    change: function(event) {
        this.setState({value: parseFloat(event.target.value)});
    },
    render: function() {
        return <input type="number" value={this.state.value} onChange={this.change}/>;
    }
});

React.render(<App/>, document.body);

You can see it here: http://jsfiddle.net/2hauj2qg/ 你可以在这里看到它: http//jsfiddle.net/2hauj2qg/

The problem is that if I want to type in a number like: "4.7". 问题是如果我想输入一个如下数字:“4.7”。 When the user enters, "4.", it becomes "4", due to being converted to a float in back. 当用户输入“4”时,由于被转换为后面的浮动,它变为“4”。 But this interrupts what the user was typing. 但这会中断用户输入的内容。 What's the recommended way of solving this problem? 解决这个问题的推荐方法是什么?

As imjared mentioned, it's because you're using parseFloat 正如imjared所提到的,这是因为你正在使用parseFloat

this.setState({value: parseFloat(event.target.value)});

Instead, you may wish to only allow digits and the decimal. 相反,您可能希望仅允许数字和小数。 It stays stored as a string and never changes their input, but they're prevented from typing things like letters and spaces. 它保持存储为字符串并且永远不会改变它们的输入,但是它们不能输入字母和空格之类的东西。

var nonNumericRegex = /[^0-9.]+/g;

this.setState({value: event.target.value.replace(nonNumericRegex, "")});

To allow negative numbers you need to do this: 要允许负数,您需要这样做:

this.setState({
    value: event.target.value
        .replace(nonNumericRegex, "")
        .replace(/^(-.*?)-/g, "$1")
});

To enforce a leading dollar sign and no more than two decimals, and if the first character (after the $) is the decimal, prefix it with 0. 要强制执行一个前导美元符号并且不超过两位小数,并且如果第一个字符(在$之后)是十进制,则将其作为前缀加0。

this.setState({
    value: "$" + event.target.value
        .replace(nonNumericRegex, "")
        .replace(/(\.\d\d)\d+/g, "$1")
        .replace(/^\./g, "0.")
})

Remove the parseFloat and your string won't be cast to a number? 删除parseFloat并且您的字符串不会被强制转换为数字?

    change: function(event) {
        this.setState({value: event.target.value});
    }

http://jsfiddle.net/2hauj2qg/1/ http://jsfiddle.net/2hauj2qg/1/

If it doesn't make sense to do anything with the number until they're done typing and you follow the standard way of raising an event to signal changed data, you can accomplish it with the following: 如果在完成输入之前对数字执行任何操作没有意义,并且您按照标准方式引发事件以指示已更改的数据,则可以使用以下方法完成此操作:

var MyComponent = React.createClass({
    getInitialState: function() {
        return {value: 4.5};
    },
    change: function(event) {
        this.setState({value: event.target.value});
    },
    blur: function(event) {
        this.props.onChange({value: parseFloat(event.target.value)});
    },
    render: function() {
        return <input type="number" value={this.state.value} onBlur={this.blur} onChange={this.change}/>;
    }
});

React.render(<MyComponent/>, document.body);

It doesn't make too much sense in this isolated example, but if you assume someone is using MyComponent and that they give it an onChange callback, then this works nicely. 在这个孤立的例子中它并没有多大意义,但是如果你假设某人正在使用MyComponent并且他们给它一个onChange回调,那么这很好用。 You get the benefits of a native input control but still return (through the callback) the number as an actual float. 您可以获得原生输入控件的好处,但仍然(通过回调)将数字作为实际浮点数返回。

What about writing a small component that will handle string values and pass only legal float values to the listeners ? 如何编写一个小组件来处理字符串值并将合法的浮点值传递给侦听器呢?

class NumberInput extends React.Component<{ onChange: (n: number) => void, value: number }, { value: number }> {

  constructor(props: { onChange: ((n: number) => void); value: number }, context: any) {
    super(props, context);
    this.state = {
      value: props.value || 0
    };
  }

  handleInputChange = (e) => {
    const value = e.target.value;
    this.setState({
      value: value
    });
    if (this.props.onChange) {
      const floatValue = parseFloat(value);
      if (!isNaN(floatValue)) {
        this.props.onChange(floatValue)
      }
    }
  };

  componentWillReceiveProps(newProps) {
    this.setState({
      value: newProps.value
    })
  }

  render() {
    return (
      <Input step="0.1" value={this.state.value} onChange={this.handleInputChange} type="number"/>
    )
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM