You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Hooks开发:表单提交失败却显示成功提示框求助

React Hooks表单提交错误时仍显示成功提示框的问题解决

核心问题分析

  1. 异步状态更新导致错误信息未生效:setWeHavError(e)是异步操作,紧接着调用toggleShowAlert(weHavError)时,weHavError还是旧的空对象,新的错误状态还未更新。
  2. 变量作用域错误:AlertElement中if分支内用const重新声明的alertMessage、alertColour、alertIcon是局部变量,不会覆盖外层的同名变量,所以无论是否出错,最终渲染的都是成功提示内容。
  3. 参数传递与重名冲突: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 18:15:03