单击“提交”会调用我的onSubmit
函数,它会执行两项操作:
formValidity
(bool)的setState 问题是第一次点击失败,第二次只提交。 我知道这是来自eval提交的,即使它还没有设置状态并且在第一次运行时失败。
我希望onSubmit预先形成setStates,然后只需一次点击就可以预先形成eval来发送邮件。
请注意:我已经尝试拆分功能并且结果相同。
我假设这里有回调,但我不知道如何正确应用ES6。
<button onClick={(event) => this.onSubmit(event)}>Submit</button>
onSubmit = (event) => {
event.preventDefault();
if (!validator.isEmail(this.state.email)) {
this.setState({
errorType: this.state.formErrors["email"],
formValidity: false
})
} else {
this.setState({
formValidity: true
})
}
if (!validator.isAlpha(this.state.fName) || !validator.isAlpha(this.state.lName)) {
this.setState({
errorType: this.state.formErrors["name"],
formValidity: false
})
} else {
this.setState({
formValidity: true
})
}
if (this.state.formValidity === true) {
console.log('mail sent!');
} else {
console.log('One of the inputs is erroneous');
}
}
只是为了确保我解释得很好,我希望if (this.state.formValidity === true)
仅在**所有其他条件eval&d; d并保持在相同的函数范围之后运行**。
感谢, 芽
答案 0 :(得分:2)
从按钮中删除事件处理程序并将其添加到表单元素:
<form onSubmit={this.handleOnSubmit}>
并在构造函数中绑定this.handleOnSubmit
。
关于您的检查,我建议您在更改事件时对每个输入字段执行检查,并相应地更新状态。例如:
<input name="email" onChange={this.validateEmail}>
此(绑定)功能可以检查email
字段,如果它有效且name
字段有效,只需将this.formValidity
状态更新为true。 / p>
然后,在您的handleOnSubmit
函数中,删除除表单验证检查之外的所有内容。
编辑:
更改所有输入'onChange
处理程序,以包含对特定函数的引用,该函数将对某些输入字段执行验证(并更新相应字段的值 - 如果您已使用该值)。例如(参考之前的输入字段):
validateEmail() {
// Update input's state value
// Perform validation for email input and update corresponding state
}
现在问题是,我建议你创建额外的状态属性(每个输入字段一个)来跟踪单个字段的有效性状态,如下所示:
this.state = {
...,
fNameValid: false,
lNameValid: false,
emailValid: false,
telValid: false,
}
现在,您的特定验证函数将仅更新与特定字段有关的状态,而不是整个表单(以及您的errorType):
validateEmail() {
// Update input's state value
if (!validator.isEmail(this.state.email)) {
this.setState({
emailValid: false,
errorType: this.state.formErrors["email"],
})
} else {
this.setState({
emailValid: true
})
}
}
最后,让您的onSubmit
事件处理程序执行所有字段的检查:
handleOnSubmit() {
let isFormValid = this.state.fNameValid
&& this.state.lNameValid
&& this.state.emailValid
&& this.state.telValid;
if (isFormValid) {
console.log('mail sent!');
} else {
console.log('One of the inputs is erroneous');
}
}
状态formValidity
属性最终变得多余。
答案 1 :(得分:1)
你需要从州测试formValidity
的价值吗?如果不是,则if (this.state.formValidity === true)
过度,您可以重新构建逻辑,以便setState
的异步性更容易解释 - 例如:
onSubmit = event => {
event.preventDefault()
let formValidity = true
let errorType = undefined
if (!validator.isEmail(this.state.email)) {
formValidity = false
errorType = this.state.formErrors.email
} else if (!validator.isAlpha(this.state.fName) || !validator.isAlpha(this.state.lName)) {
formValidity = false
errorType = this.state.formErrors.name
}
if (!formValidity) {
this.setState({
formValidity,
errorType
}, () => console.log('Form is invalid'))
} else {
this.setState({
formValidity,
errorType
}, () => console.log('Form is valid'))
}
}
您还会看到我利用setState
的回调,可以安全地假设只有在设置状态后才能运行。
答案 2 :(得分:0)
setState是一个异步函数,您可以添加邮件发送代码或依赖于formValidity = true的任何此类代码作为setState函数的回调,因此不需要最后一个if-else块。总是避免最后一个if-else阻塞,因为setState以异步方式运行。
this.setState({
formValidity: true
},function(){
console.log("mail sent");
//or any other code dependent on formValidity set to true.
});