React Hooks开发:表单提交失败却显示成功提示框求助
React Hooks表单提交错误时仍显示成功提示框的问题解决
核心问题分析
- 异步状态更新导致错误信息未生效:
setWeHavError(e)是异步操作,紧接着调用toggleShowAlert(weHavError)时,weHavError还是旧的空对象,新的错误状态还未更新。 - 变量作用域错误:
AlertElement中if分支内用const重新声明的alertMessage、alertColour、alertIcon是局部变量,不会覆盖外层的同名变量,所以无论是否出错,最终渲染的都是成功提示内容。 - 参数传递与重名冲突:
AlertElement的参数和组件内state重名,且调用时未正确传递当前错误状态。
修正方案与代码示例
1. 修复AlertElement的变量作用域问题
将默认提示变量改为let声明,避免分支内局部变量覆盖失效:
const ContactPage = () => { const [weHavError, setWeHavError] = useState({}); const [visibility, setVisibility] = useState(false); // 新增state标记是否为错误弹窗 const [isErrorAlert, setIsErrorAlert] = useState(false); // 重命名参数避免与state冲突 const AlertElement = ({ hasError }) => { let alertMessage = "Thank you. Your contact information was submitted successfully."; let alertColour = "success"; let alertIcon = "fa-check-circle"; if (hasError) { alertMessage = "We are sorry there was an error in submitting your information. Please try again later"; alertColour = "danger"; alertIcon = "fa-times-circle"; } return ( <MDBAlert key="1" color={alertColour} autohide width={350} position="top-center" offset={50} delay={3500} appendToBody show={visibility} > <div className="d-flex justify-content-between"> <div className="p-0"> <i className={`fas ${alertIcon} me-3`}></i> </div> <div className="p-0">{alertMessage}</div> <div className=""> <MDBBtn id="alertButt" className="btn-close" noRipple outline color="none" onClick={toggleShowAlert} /> </div> </div> </MDBAlert> ); };
2. 修正提交逻辑与弹窗控制
直接传递错误状态给弹窗控制函数,避免异步state更新的延迟问题:
const toggleShowAlert = (isError = false) => { setVisibility(true); setIsErrorAlert(isError); }; const onSubmit = async (values, actions) => { try { const response = await axios.post("/", { values }); // 成功时标记为非错误弹窗 toggleShowAlert(false); console.log("This shows if SUCCESS"); await new Promise((resolve) => setTimeout(resolve, 1000)); } catch (e) { // 错误时直接传递状态,无需等待state更新 toggleShowAlert(true); setWeHavError(e); } };
3. 正确调用AlertElement
// 在组件渲染区域添加 <AlertElement hasError={isErrorAlert} />
补充说明
你之前控制台同时出现"Things look good"和"There was an error",是因为AlertElement中先执行了外层的console.log("Things look good"),随后进入if分支打印错误日志,但由于变量作用域问题,实际渲染的还是外层的成功提示变量。
内容的提问来源于stack exchange,提问作者JohnM
相关产品推荐
相关产品推荐

