React表单存在校验错误时如何阻止表单提交?
问题原因
React的setState类更新方法是异步批量执行的,你在registerUser函数中调用setFormErrors后,当前函数作用域内的formErrors还是更新前的旧值(也就是初始的空对象),所以后续判断Object.keys(formErrors).length === 0永远成立,就会直接触发提交逻辑。等到组件下一次重渲染时,formErrors才会更新为带错误提示的值,所以你会看到页面展示了错误但表单已经提交的矛盾表现。
修复方案
你不需要用useRef,最简单的方案是先在内存中收集所有校验错误,再统一判断和更新状态:
const [formErrors, setFormErrors] = useState({}); const registerUser = () => { // 先声明临时错误对象收集所有校验问题 const newErrors = {}; if (firstName === "") { newErrors.firstName = "Firstname is required!"; } if (lastName === "") { newErrors.lastName = "Lastname is required!"; } // 直接判断临时错误对象的长度,不受异步更新影响 if (Object.keys(newErrors).length === 0) { console.log("Form Submitted"); // 提交成功可以清空之前的错误 setFormErrors({}); } else { console.log("Failed"); // 有错误再统一更新状态触发重渲染展示提示 setFormErrors(newErrors); } }
这个方案既避免了state异步更新的判断问题,又能正常触发组件重渲染展示错误提示,逻辑更清晰性能也更好。
内容的提问来源于stack exchange,提问作者Mir Stephen
相关产品推荐
相关产品推荐

