【问题标题】:React Component and Invalid InputReact 组件和无效输入
【发布时间】:2015-02-21 04:33:27
【问题描述】:

我有以下反应组件:

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

你可以在这里看到它:http://jsfiddle.net/2hauj2qg/

问题是,如果我想输入一个数字,例如:“4.7”。当用户输入“4.”时,它变为“4”,因为在后面被转换为浮点数。但这会打断用户正在输入的内容。解决此问题的推荐方法是什么?

【问题讨论】:

    标签: javascript validation input reactjs


    【解决方案1】:

    删除 parseFloat 并且您的字符串不会被转换为数字?

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

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

    【讨论】:

      【解决方案2】:

      正如 imjared 所说,这是因为您使用的是 parseFloat

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

      相反,您可能希望只允许数字和小数。它以字符串形式存储,从不更改其输入,但无法输入字母和空格等内容。

      var nonNumericRegex = /[^0-9.]+/g;
      
      this.setState({value: event.target.value.replace(nonNumericRegex, "")});
      

      要允许负数,您需要这样做:

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

      强制使用前导美元符号且小数点不超过两位,如果第一个字符($ 之后)是小数点,则在其前面加上 0。

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

      【讨论】:

      • 正如我在问题中指出的那样,我知道这是因为 parseFloat。您的解决方案会让我存储字符串,但我想要数据模型中的实际数字,而不是字符串。
      • this.state 是 ui 状态,您可以先转换为数字,然后再将其传递到其他地方。据我所知,没有更好的解决方案。
      【解决方案3】:

      如果在他们完成输入之前对数字执行任何操作都没有意义,并且您遵循引发事件以指示更改的数据的标准方法,则可以通过以下方式完成:

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

      在这个孤立的例子中没有太大意义,但如果你假设有人在使用 MyComponent 并且他们给它一个 onChange 回调,那么这很好用。您可以获得本机输入控件的好处,但仍然(通过回调)将数字作为实际浮点数返回。

      【讨论】:

        【解决方案4】:

        编写一个处理字符串值并仅将合法浮点值传递给侦听器的小组件怎么样?

        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"/>
            )
          }
        }
        

        【讨论】:

          猜你喜欢
          • 2021-02-27
          • 1970-01-01
          • 1970-01-01
          • 2017-07-16
          • 1970-01-01
          • 2020-11-29
          • 1970-01-01
          • 2018-01-02
          • 1970-01-01
          相关资源
          最近更新 更多