我的页面上有个获取验证码的功能,在获取验证码之前需要验证手机号是否正确,所以我这么写了代码
// 发送验证码
const handleSendSms = async time => {
// 验证手机
console.info('account1', account);
// 验证手机号是否正确
validate('account', values.account);
console.info('account2', account);
if (account.error) {
setSnackbar({ open: true, message: '手机输入错误' });
return;
}
// 后面省略。。。
}
validate函数如下
const validate = (name, value) => {
if (name === 'account') {
if (!value) {
setAccount({ ...account, error: true });
console.info('account setAccount', account);
} else {
setAccount({ ...account, error: false, helperText: '' });
}
}
//后面省略
}
state代码
const valueInit = {
error: false,
helperText: '',
};
// validate
const [account, setAccount] = useState(valueInit);
// values
const [values, setValues] = useState({
account: '',
});
按我的预想,我点击了获取验证码之后,会在validate()那return掉,事实是console日志结果在setAccount之后输出了error是false,导致最后没有拦截成功,这是为什么呢?是因为异步的原因吗,这种情况怎么处理呢?
account1 {error: false, helperText: ""}
account setAccount {error: false, helperText: ""}
account2 {error: false, helperText: ""}
你试一下结果。 // setState 是异步的
解决办法:
让 validate 函数更加纯粹,变成一个没有副作用的纯函数,把验证结果返回给调用者,更新 state 的活不该它来干。这样一来, handleSendSms 里可以验证 validate 的返回值,而不是 account.error。