Javascript React是否在状态更改时放弃排队事件?
我正在制作一个带有简单验证的React表单组件。每个字段都在模糊上进行验证,表单有一个简单的Javascript React是否在状态更改时放弃排队事件?,javascript,reactjs,forms,validation,dom-events,Javascript,Reactjs,Forms,Validation,Dom Events,我正在制作一个带有简单验证的React表单组件。每个字段都在模糊上进行验证,表单有一个简单的onSubmit函数。布尔值存储在字段是否应显示错误消息的状态中,并在验证期间更新 除了字段的onBlur和表单的`onSubmit同时被触发外,其他一切都正常工作。i、 e.我在字段中键入一些内容,然后立即单击“提交”按钮 首先执行onBlur,如果验证状态没有发生变化,则按预期执行onSubmit。但是,如果onBlur更改状态,则永远不会调用onSubmit函数 所以我的问题是,;组件中的设置状态是
onSubmit
函数。布尔值存储在字段是否应显示错误消息的状态中,并在验证期间更新
除了字段的onBlur
和表单的`onSubmit同时被触发外,其他一切都正常工作。i、 e.我在字段中键入一些内容,然后立即单击“提交”按钮
首先执行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'));
类SimpleForm扩展了React.Component{
建造师(道具){
超级(道具);
this.handleBlur=this.handleBlur.bind(this);
this.state={shouldbarhorror:false}
}
车把(活动){
控制台日志(“模糊”)
const isEmpty=event.target.value==“”
this.setState({shouldbarhorror:isEmpty})
}
handleSubmit(事件){
event.preventDefault()
控制台日志(“提交”)
}
render(){
报税表(
)
}
};
ReactDOM.render(一个可以让你自己看到错误的地方。欢迎提供任何帮助。是的,更改组件中的状态将清除所有排队事件,因为状态更改将导致整个组件重新呈现,并且事件将被清除并重新附加 我将在submit事件回调中进行验证,而不是在blur事件回调中进行验证。如果要在用户键入时进行验证,可以使用
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'));
类SimpleForm扩展了React.Component{
建造师(道具){
超级(道具);
this.handleBlur=this.handleBlur.bind(this);
this.state={shouldbarhorror:false}
}
车把(活动){
控制台日志(“模糊”)
const isShowingError=this.state.shouldFlowerRor;
const isEmpty=event.target.value==“”
if(isShowingError&!isEmpty){
控制台日志(“提交表格”);
}
this.setState({shouldbarhorror:isEmpty})
}
handleSubmit(事件){
event.preventDefault()
控制台日志(“提交”)
}
render(){
报税表(
)
}
};
ReactDOM.render(感谢Manolo确认了我的怀疑,即是状态更改清除了事件队列。我想我已经找到了一个暂时可行的解决方案: 如果需要同时执行onBlur和onSubmit主体,可以在setTimeout中包装onBlur主体,以便将其放入任务队列并在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 })
}
}
我很高兴事情是这样的,不仅仅是我疯了。关于您的建议,部分要求是对blur进行验证,因为onKeyUp或onChange会过早地显示电子邮件字段的错误消息。此外,表单中有8个字段,因此仅在提交时进行验证对用户来说并不特别友好。但是,验证失败时,您不需要提交表单,如果提交表单时状态在模糊上没有改变,则表单将被提交(提交事件回调将被执行)。这是正确的。当显示字段的错误消息时,用户会更正该错误消息,然后单击submit。在这种情况下,表单应该提交,因为表单是有效的,但它不是,因为onBlur中的状态更改正在取消onSubmit事件。不幸的是,我也不能执行您的最新建议。表单应仅在单击提交按钮时提交。