【发布时间】: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