我正在用简单的验证制作一个React表单组件。每个字段都在模糊上进行验证,并且表单具有一个简单的onSubmit
函数。布尔值存储在字段是否应该显示错误消息的状态中,并在验证期间更新。
除了字段的onBlur
和表单的‘`onSubmit同时被触发时,一切都正常工作。也就是说,我在字段中键入某项内容,然后立即单击submit按钮。
首先执行onBlur
,如果不更改验证状态,则按预期执行onSubmit
。但是,如果onBlur
更改了状态,则onSubmit
函数永远不会被称为。
因此,我的问题是:在组件中设置状态是否清除了任何排队事件,是否有可能解决此问题?
下面是我的代码的简化版本:
class SimpleForm extends React.Component {
constructor(props) {
super(props);
this.handleBlur = this.handleBlur.bind(this);
this.state = { shouldShowError: false }
}
handleBlur(event) {
console.log("blur")
const isEmpty = event.target.value === ""
this.setState({ shouldShowError: isEmpty })
}
handleSubmit(event) {
event.preventDefault()
console.log("submit")
}
render() {
return (
< form onSubmit = { this.handleSubmit} >
< input type = "text" onBlur = { this.handleBlur } />
{ this.state.shouldShowError ? < p > This field is required. < /p> : null }
< button type = "submit" > Submit < /button >
< /form>
)
}
};
ReactDOM.render(< SimpleForm / >, document.getElementById('container'));
和一个JSFiddle,它应该允许您自己看到错误。任何帮助都是值得感激的。
发布于 2016-04-09 03:51:04
感谢马诺洛证实了我的怀疑,那就是状态的变化抹掉了事件队列。我想我已经找到了一个解决方案,现在可以:
如果需要同时执行onBlur和onSubmit主体,则可以将onBlur主体封装在setTimeout中,以便将其放在任务队列中并在onSubmit之后执行:
handleBlur(event) {
const value = event.target.value
setTimeout(() => {
console.log("blur")
const isEmpty = value === ""
this.setState({ shouldShowError: isEmpty })
}, 10)
}
注意,在react中,默认情况下不能异步访问事件,因此需要提取超时之外需要的值,或者调用event.persist()。
我不需要onBlur主体来执行,因为我的onSubmit也验证了表单。读了一会儿之后,我发现您可以调用event.relatedTarget来访问焦点转移到的组件。因此,我可以检查它是否是submit按钮,并且只有当它不是onBlur主体时才执行它:
handleBlur(event) {
if (!event.relatedTarget || event.relatedTarget.id !== 'submit') {
console.log("blur")
const isEmpty = event.target.value === ""
this.setState({ shouldShowError: isEmpty })
}
}
发布于 2016-04-09 02:23:04
是的,更改组件中的状态可以清除任何排队事件,因为状态更改会导致重新呈现整个组件,并清除和重新附加事件。
我将在submit事件回调中进行验证,而不是模糊事件回调。如果要在用户输入时进行验证,可以使用onKeyUp
。
如果希望保留示例行为,则可以在显示错误且没有错误时在onBlur
回调中提交表单:
class SimpleForm extends React.Component {
constructor(props) {
super(props);
this.handleBlur = this.handleBlur.bind(this);
this.state = { shouldShowError: false }
}
handleBlur(event) {
console.log("blur")
const isShowingError = this.state.shouldShowError;
const isEmpty = event.target.value === ""
if (isShowingError && !isEmpty) {
console.log("submit the form");
}
this.setState({ shouldShowError: isEmpty })
}
handleSubmit(event) {
event.preventDefault()
console.log("submit")
}
render() {
return (
< form onSubmit = { this.handleSubmit} >
< input type = "text" onBlur = { this.handleBlur } />
{ this.state.shouldShowError ? < p > This field is required. < /p> : null }
< button type = "submit" > Submit < /button >
< /form>
)
}
};
ReactDOM.render(< SimpleForm / >, document.getElementById('container'));
https://stackoverflow.com/questions/36514629
复制