React中使用自定义handleSubmit时表单无法正常post提交该如何解决
问题原因
你在handleSubmit开头就调用了e.preventDefault(),这个方法会直接终止表单的默认提交行为,一旦调用后,无论后续函数返回什么值,都不会再触发原生的表单提交动作,这是浏览器DOM事件的标准规则,和React的事件封装逻辑也一致。
补充说明:React的事件处理函数仅在返回false时会自动触发e.preventDefault(),返回true没有特殊含义,无法恢复已经被阻止的默认行为,这也是你明明返回true却无法提交的核心误区。
解决方案
方案1:仅在校验失败时阻止默认行为
最简单的改法是把e.preventDefault()移到校验不通过的分支中,校验全部通过的话不调用该方法,原生提交逻辑会自动执行:
const handleSubmit = (e) => { let password = e.target.password.value; let confirmPassword = e.target.confirmPassword.value; let email = e.target.email.value; let emailRegex = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; if (!emailRegex.test(email)) { e.preventDefault(); setError(true) setErrorMessage("invalid email address."); return; } if (password !== confirmPassword) { e.preventDefault(); setError(true) setErrorMessage("passwords do not match."); return; } setError(false) console.log("reached end") // 校验通过,无阻止逻辑,表单自动提交 }
方案2:校验通过后主动触发表单提交
如果后续有异步校验等需求,必须提前阻止默认行为的话,校验通过后主动调用表单的submit()方法即可,该方法触发的提交不会再次触发submit事件,不会出现死循环:
const handleSubmit = (e) => { e.preventDefault(); let password = e.target.password.value; let confirmPassword = e.target.confirmPassword.value; let email = e.target.email.value; let emailRegex = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; if (!emailRegex.test(email)) { setError(true) setErrorMessage("invalid email address."); return; } if (password !== confirmPassword) { setError(true) setErrorMessage("passwords do not match."); return; } setError(false) console.log("reached end") // 校验通过,主动提交表单 e.target.submit(); }
内容的提问来源于stack exchange,提问作者Hunter Scott Lacefield
相关产品推荐
相关产品推荐

