React中函数执行后调用API异常:校验不通过仍触发请求
React中验证完成后才调用API的问题解决
你的问题核心出在两个地方,咱们一步步拆解:
问题根源
- 回调无条件执行:当前的
validate函数不管验证是否通过,最后都会直接调用callback()。哪怕你在验证不通过时设置了isValid=false,这个回调还是会被触发。 - useState的异步特性:
setValidation(false)是异步更新状态的,当你调用callback()时,isValid的实际值还没变成false,所以validateUserCredentials里的if (isValid)依然会拿到之前的true,进而执行API调用。
解决方案
我们可以调整validate的逻辑,只有验证通过时才执行回调,同时避免依赖异步更新的isValid状态来做判断。这里有两种简洁的实现方式:
方式一:在validate内部控制回调执行
修改validate函数,先同步判断验证是否通过,只有通过时才调用回调:
const validate = (callback) => { let isValidationPassed = true; if (code == null || code.trim().length === 0) { setValidation(false); setValidationMessage(translate.signIn.codeErrorMessage); setVisible(true); isValidationPassed = false; } else if (phoneNumber == null || phoneNumber.trim().length === 0) { setValidation(false); setValidationMessage(translate.signIn.phoneErrorMessage); setVisible(true); isValidationPassed = false; } // 仅验证通过时才执行回调 if (isValidationPassed) { callback(); } }
方式二:让validate返回验证结果,在onSubmit中判断
这种方式更直观,不需要回调,直接在onSubmit里根据验证结果决定是否调用API:
const validate = () => { if (code == null || code.trim().length === 0) { setValidation(false); setValidationMessage(translate.signIn.codeErrorMessage); setVisible(true); return false; } else if (phoneNumber == null || phoneNumber.trim().length === 0) { setValidation(false); setValidationMessage(translate.signIn.phoneErrorMessage); setVisible(true); return false; } // 验证通过时更新状态并返回true setValidation(true); return true; } const onSubmit = () => { const isPassed = validate(); if (isPassed) { validateUserCredentials(); } }
额外提示
建议尽量避免依赖刚通过useState设置的状态立刻做判断,因为React的状态更新是异步批量处理的,直接读取可能拿到旧值。像上面的两种方式,都是先同步确定验证结果,再做后续操作,这样更可靠。
内容的提问来源于stack exchange,提问作者Sunny
相关产品推荐
相关产品推荐

