我在 React 中创建了表单,但在验证方面遇到了问题。
当我们点击(下面的示例和演示)提交表单
而不填写输入字段时,我们应该会收到错误。这很好用。然而,同时我们也收到了成功消息,这意味着这个条件 (!this.state.firstNameError && !this.state.lastNameError)
返回 true
,但是不应该。仅在第二次单击时才能正常工作。
发生这种情况是因为 setState
没有立即更新,我猜。
我正在寻找解决此问题的好方法。
我可以用一种方法进行验证和提交,并在错误的 setState
之后的回调中将 success
设置为 true
。但我不想在一种方法中保存这么多代码(我的实际形式要大得多)。什么是更好的解决方案?
一个简单的代码示例:
class App extends Component {
state = {
firstName: "",
firstNameError: false,
lastName: "",
lastNameError: false,
success: false
};
inputHandler = e => this.setState({ [e.target.name]: e.target.value });
validateForm = () => {
this.setState({
firstNameError: false,
lastNameError: false,
success: false
});
if (!this.state.firstName) this.setState({ firstNameError: true });
if (!this.state.lastName) this.setState({ lastNameError: true });
};
formSubmit = e => {
e.preventDefault();
this.validateForm();
if (!this.state.firstNameError && !this.state.lastNameError) {
this.setState({ success: true });
}
};
render() {
const { firstNameError, lastNameError, success } = this.state;
return (
<div className="container">
<form onSubmit={this.formSubmit}>
<div className="row">
<label>First Name: </label>
<input onChange={this.inputHandler} name="firstName" type="text" />
</div>
{firstNameError && <div className="error">Enter First Name</div>}
<div className="row">
<label>Last Name: </label>
<input onChange={this.inputHandler} name="lastName" type="text" />
</div>
{lastNameError && <div className="error">Enter Last Name</div>}
<div className="row">
<button>Submit Form</button>
</div>
{success && <div className="success">Success</div>}
</form>
</div>
);
}
}
最佳答案
在validateForm
中,找出每个字段的有效状态,然后用它来确定整个表单是否有效,并且只调用setState
一次。
validateForm = () => {
const firstNameError = !this.state.firstName;
const lastNameError = !this.state.lastName;
this.setState({
firstNameError,
lastNameError,
success: !lastNameError && !firstNameError,
});
};
formSubmit = e => {
e.preventDefault();
this.validateForm();
};
注意 - 根据其复杂程度以及表单的实际提交方式,您可以决定这是否需要是两个不同的函数。如果您正在等待 this.state.success
为 true 来提交表单,请使用 setState
的回调来执行此操作。
this.setState(validatedState, newState => if (this.newState.success) submit() );
关于javascript - 当 setState 没有立即运行时验证表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55939041/