我正在制作一个带有简单验证的 React 表单组件。每个字段都经过模糊验证,并且表单具有简单的 onSubmit
函数。 bool 值存储在字段是否应显示错误消息的状态中,并且在验证期间更新。
除了字段的 onBlur 和表单的 onSubmit 同时触发之外,一切正常。即,我在字段中输入一些内容,然后立即单击提交按钮。
首先执行 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这应该可以让您自己看到错误。任何帮助总是值得赞赏。
最佳答案
感谢 Manolo 证实了我的怀疑,即状态更改删除了事件队列。我想我已经找到了目前可行的解决方案:
如果您需要同时执行 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.latedTarget 来访问焦点转移到的组件。所以我可以检查它是否是提交按钮,如果不是,则仅执行 onBlur 主体:
handleBlur(event) {
if (!event.relatedTarget || event.relatedTarget.id !== 'submit') {
console.log("blur")
const isEmpty = event.target.value === ""
this.setState({ shouldShowError: isEmpty })
}
}
关于javascript - React 会在状态更改时丢弃排队事件吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36514629/