【问题标题】:React js input invalid while user types (I want to validate onBlur instead of onChange)用户输入时反应 js 输入无效(我想验证 onBlur 而不是 onChange)
【发布时间】:2016-10-17 00:07:51
【问题描述】:

我遇到过几次这个问题,我正在寻找解决这个问题的“反应方式”。

问题

用户键入时,数字字段暂时无效。例如:“-45”是“-”,“2.3”是“2.”。最简单的验证示例只是对值进行 parseFloat。这是一个工作示例:http://jsfiddle.net/h55kruca/6/。我正在寻找一种方法来验证 onBlur 而不是 onChange,或者类似的方法来实现这一点。

这是示例中的 JS:

var App = React.createClass({
    getInitialState: function() {
        return {number: 0}
    },    
    handleNumberChange: function(e) {
        var val = parseFloat(e.target.value);
        this.setState({number: val});
    },
    render: function() {
        return (
            <Editor number={this.state.number}
                    onNumberChange={this.handleNumberChange}
            />
        );
    }
});

var Editor = React.createClass({
    render: function() {
        return (
            <form className="reactForm" >
                <input type='text'
                       value={this.props.number}
                       onChange={this.props.onNumberChange} />
                <span>{this.props.number}</span>
            </form>
        );
    }
});

请注意,验证(在这种情况下为parseFloat)发生在父级或祖级中(并最终存储在服务器上),编辑器的props.number 会因用户输入或来自服务器。这是受控组件的原因。

方法#0

我尝试使用 onBlur 代替 onChange,react 给了我这个警告:Warning: Failed form propType: You provided a 'value' prop to a form field without an 'onChange' handler. This will render a read-only field. If the field should be mutable use 'defaultValue'. Otherwise, set either 'onChange' or 'readOnly'.

方法#1

存储一个实际上是字符串的临时“数字”状态。将它用于用户在输入中键入的任何内容,直到 onBlur。我不喜欢这样,因为实现如此简单的事情需要大量的代码。我可能最终会在每个输入元素周围创建一个包装器(对我来说很痛苦)。

方法#2

将输入包装在一个组件中,该组件使用 shouldComponentUpdate 停止更新,直到 onBlur。这再次需要对每个输入进行包装。

方法#3

通过取出value= 使输入成为不受控制的组件。我还没有完全考虑到这一点,但我想我很快就会错过受控组件的功能。如果有办法在受控和不受控的 onFocus 和 onBlur 之间切换,也许这就是我的答案。

您的解决方案

必须有一种简单的方法来解决这个问题,或者至少在 React 社区中正在开发一些东西,我就是找不到任何东西。你是怎么解决这个问题的?

【问题讨论】:

  • 我认为我的第一个例子让人们感到困惑,因为它有点过于简单化了。我已将其换成 2 层示例。这里的App 应该只将 state.number 设置为有效数字(不是字符串)。
  • 这方面有什么更新吗?对于不应该具有低于某个数字的值的输入,我遇到了同样的问题。当您擦除并且值低于最小值时,onChange 中的验证显然会产生奇怪的行为。
  • 最终使用了方法 1,对于如此简单的事情确实很痛苦。但在这一点上我真的没有看到任何其他方式。
  • 是的@GeoffreyHug,我也在多种情况下采用了方法1。不过,那个临时状态变量真的让我很困扰!我还没有尝试创建我提到的包装器。你不认为这会成为 React 社区中的一个常见问题吗?

标签: javascript validation reactjs onblur


【解决方案1】:

要验证onBlur,您可以更改您的输入:

&lt;input type='text' value={this.state.number} onChange={this.handleNumberChange} /&gt;

到这里:

&lt;input type='text' onBlur={this.handleNumberChange} /&gt;

【讨论】:

  • 这能回答你的问题吗?无法真正按照您的要求进行操作。
  • 这是我的方法#3,通过删除 value= 使其不受控制。然后我需要一种方法来随着数据的变化(我想要控制它的原因)更新它。
【解决方案2】:

您可以使用以下代码代替

var App = React.createClass({
    getInitialState: function() {
        return {number: 0}
    },    
    handleNumberChange: function(e) {
        var val = parseFloat(e.target.value);
        this.setState({number: val});
    },
    render: function() {
        return (
            <form className="reactForm" >
                <input type='text'
                       value={this.props.number}
                       onBlur={this.handleNumberChange} />
                <span>{this.state.number}</span>
            </form>
        );
    }
});

App.defaultProps = { number: 0 };

React.render(
    <App />,
    document.getElementById('app')
);

注意:要显示其他人的价值,您将其设置为:

React.render( <App number="10"/>, document.getElementById('app') );

您可以作为道具发送给组件的任何类型的值。

【讨论】:

  • 这是一种你可以使用的方法。
  • 我意识到我遗漏了一个方法。我现在添加了#0。那是我尝试的第一件事,这基本上就是你所做的。我相信您打算将 value= 更改为 defaultValue= 并使其成为不受控制的元素,这是我的方法 #3。
  • 是的,我只是将默认值分隔/设置为道具,然后 onBlur 处理并更新状态值。
  • 我看到了,当通过输入更改数字时它可以工作,但它不会呈现来自另一个来源的 state.number 更改(例如来自服务器的新数据)。
  • 对于服务器端数据,您可以注入例如 function mapStateToProps(state) { return { number: state.number } } export default connect(mapStateToProps)(App)。这将通过 redux.js 将 state 转换为 props。
【解决方案3】:

您的初始方法非常接近工作。只需将 value 更改为 defaultValue。

<input type='text' defaultValue={this.props.number} onChange={this.props.onNumberChange} />

【讨论】:

  • 这将在每个字符更改时验证,而不是在用户离开控件时验证
猜你喜欢
  • 1970-01-01
  • 2015-12-23
  • 1970-01-01
  • 2021-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-19
  • 1970-01-01
相关资源
最近更新 更多