javascript - 访问 this.state 后如何确保 setState 调用已经执行?
问题描述
我有一个注册表。当我单击“注册”按钮时,所有TextInputs
内容都已验证,并且对于每个字段,我都会调用一个函数,我在其中调用 eg this.setState({usernameError: 'This field is required'})
。因此,对于每个文本字段,我都有一个函数来设置该字段的错误状态。在我按下注册按钮后,我想验证所有字段,然后如果状态中有任何字段错误,则返回函数(如果所有字段都没有正确填写,用户可能无法注册)。问题是:因为setState
是异步的,所以当我检查它们时,不能保证所有字段错误都已经正确设置。
2个重要注释:
- 我知道 setState 的第二个参数(回调),但我无法在此回调中执行条件(检查状态中的字段错误),因为 setState 调用位于它们自己的函数中
- 它们位于自己的函数中,因为我想重用逻辑(我也在
validate<FieldName>
其他地方调用函数,例如当onChangeText
事件发生时)
所以我的问题是:如何确保在检查其值而不放弃我可重用的“验证器函数”时状态已经更新?
一些代码使其更清晰:
state = { usernameError: '', firstNameError: '', lastNameError: '' };
setUsernameError = () => { // This function is also called elsewhere than in handlePressRegister
const { username } = this.state;
if (username === '')
this.setState({ usernameError: 'Required field' });
else if (username.length < 2)
this.setState({ usernameError: 'Minimum 2 characters' });
else
this.setState({ usernameError: undefined });
}
setFirstNameError = () => { // This function is also called elsewhere than in handlePressRegister
...shortened for brevity...
}
setLastNameError = () => { // This function is also called elsewhere than in handlePressRegister
...shortened for brevity...
}
handlePressRegister = () => {
const { usernameError, firstNameError, lastNameError } = this.state;
this.setUsernameError();
this.setFirstNameError();
this.setLastNameError();
if (usernameError || firstNameError || lastNameError) // The errors may not be set in the state yet
return;
我希望你能正确理解我的问题。
解决方案
如果你promisify setState
,你可以从每个验证器调用中返回它并调用Promise.all
它:
setUsernameError = () => { // This function is also called elsewhere than in handlePressRegister
const { username } = this.state;
if (username === '')
return setStatePromisified({ usernameError: 'Required field' });
// ...
Promise.all([
this.setUsernameError(),
this.setFirstNameError(),
this.setLastNameError(),
])
.then(() => {
// state will be updated now
const { usernameError, firstNameError, lastNameError } = this.state;
if (usernameError || firstNameError || lastNameError) {
return;
}
// submit?
});
另一种选择是将另一个属性添加到状态中,例如,validating
在按下注册按钮时设置。下一个渲染,检测它在 a 中的变化componentDidUpdate
, reset validating
,并根据需要继续执行逻辑(如果没有错误,提交表单?)。