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

React Post请求成功后,后续操作(重定向/Toast/邮件)未触发问题

问题描述

我用React、Axios、ExpressJS和MySQL开发应用,需求是数据提交到数据库后,执行用户重定向、显示确认Toast及发送邮件操作。目前数据已成功存入数据库,但重定向、确认Toast和邮件发送都没执行,console.log(response)也没有输出。尝试去掉.then()处理后问题依旧,相关代码如下:

import React, { useState } from "react";
import styled from "styled-components";
import axios from "axios";
import { Toast } from "bootstrap";
import {useNavigate } from "react-router-dom";

const client = axios.create({
  baseURL: "http://localhost:9999",
});

export default function AddStructure() {
  const [assetReg, setAssetReg] = useState("");
  const [structureNameReg, setStructureNameReg] = useState("");
  const [emailReg, setEmailReg] = useState("");
  const [townReg, setTownReg] = useState("");
  const [informationReg, setInformationReg] = useState("");
  const [numberStructuresReg, setNumberStructuresReg] = useState("");
  const [newsletterReg, setNewsletterReg] = useState("");
  const [manageScheduleReg, setManageScheduleReg] = useState("");
  const [flyerReg, setFlyerReg] = useState("");
  const [drinksReg, setDrinksReg] = useState("");
  const navigate = useNavigate();

  const config = {
    SecureToken: "39ced67b-1fcc-48a2-8d18-48e5d1dc9ad8",
    To: "sport.admin@yopmail.com",
    From: emailReg,
    Subject: "confirmation creation of your structure",
    Body: `Dear partner, we are pleased to confirm the creation of your structure. ${structureNameReg}  glass.`,
  };

  const AddStructure = (e) => {
    e.preventDefault();
    if (!assetReg || !structureNameReg || !emailReg || !townReg) {
      Toast.error(
        "please provide value into asset, structure name , email and town"
      );
    } else {
      // eslint-disable-next-line no-unused-expressions
      client
        .post("/addStructure", {
          asset: assetReg,
          structure_name: structureNameReg,
          email: emailReg,
          town: townReg,
          information: informationReg,
          number_structure: numberStructuresReg,
          newsletter: newsletterReg,
          manage_schedule: manageScheduleReg,
          flyer: flyerReg,
          drinks: drinksReg,
        })
        .then((response) => {
          console.log(response);
          Toast.success("Structure added Successfully");
          if (window.email) {
            window.email.send(config);
          }
          setTimeout(() => navigate("/"), 500);
        })
        .then.catch((err) => Toast.error(err.response.data));
    }
  };
问题分析与修复步骤

1. Promise链式调用语法错误

代码里的.then.catch((err) => ...)是语法错误,正确写法应为.catch((err) => ...)。这个错误会直接导致整个Promise链失效,then内的回调根本不会执行,这是核心问题。

2. Bootstrap Toast 使用错误

原生Bootstrap的Toast类不能直接通过Toast.error()或Toast.success()静态调用,必须先在DOM中定义Toast元素,再实例化调用。

3. 后端未正确返回响应

虽然数据成功存入数据库,但如果Express后端没有在插入数据后返回响应(比如res.send()或res.json()),Axios的then回调会一直处于等待状态,永远不会触发。

4. 邮件发送API使用错误

window.email.send(config)的写法大概率不正确,常用前端邮件库(如EmailJS)需要正确初始化并调用对应API,且依赖外部脚本引入。

5. 函数名与组件名冲突

组件名为AddStructure,内部处理函数也叫AddStructure,会导致变量覆盖,引发未知问题。


修复后的代码示例

React组件部分

import React, { useState, useRef } from "react";
import styled from "styled-components";
import axios from "axios";
import { Toast } from "bootstrap";
import { useNavigate } from "react-router-dom";

const client = axios.create({
  baseURL: "http://localhost:9999",
});

export default function AddStructure() {
  const [assetReg, setAssetReg] = useState("");
  const [structureNameReg, setStructureNameReg] = useState("");
  const [emailReg, setEmailReg] = useState("");
  const [townReg, setTownReg] = useState("");
  const [informationReg, setInformationReg] = useState("");
  const [numberStructuresReg, setNumberStructuresReg] = useState("");
  const [newsletterReg, setNewsletterReg] = useState("");
  const [manageScheduleReg, setManageScheduleReg] = useState("");
  const [flyerReg, setFlyerReg] = useState("");
  const [drinksReg, setDrinksReg] = useState("");
  const navigate = useNavigate();
  const toastRef = useRef(null);
  const toastBodyRef = useRef(null);

  // 自定义Toast显示函数
  const showToast = (message, isSuccess = true) => {
    if (!toastRef.current || !toastBodyRef.current) return;
    toastBodyRef.current.textContent = message;
    // 清除之前的样式
    toastRef.current.classList.remove("bg-success", "bg-danger", "text-white");
    // 添加对应样式
    if (isSuccess) {
      toastRef.current.classList.add("bg-success", "text-white");
    } else {
      toastRef.current.classList.add("bg-danger", "text-white");
    }
    const toast = new Toast(toastRef.current);
    toast.show();
  };

  // 重命名处理函数,避免与组件名冲突
  const handleAddStructure = (e) => {
    e.preventDefault();
    if (!assetReg || !structureNameReg || !emailReg || !townReg) {
      showToast("请填写资产、机构名称、邮箱和所在地", false);
      return;
    }

    client
      .post("/addStructure", {
        asset: assetReg,
        structure_name: structureNameReg,
        email: emailReg,
        town: townReg,
        information: informationReg,
        number_structure: numberStructuresReg,
        newsletter: newsletterReg,
        manage_schedule: manageScheduleReg,
        flyer: flyerReg,
        drinks: drinksReg,
      })
      .then((response) => {
        console.log(response);
        showToast("机构添加成功");
        
        // 修复邮件发送(以EmailJS为例)
        if (window.emailjs) {
          // 替换为你的EmailJS服务ID、模板ID和用户ID
          window.emailjs.send(
            "你的服务ID",
            "你的模板ID",
            {
              to_email: "sport.admin@yopmail.com",
              from_email: emailReg,
              subject: "confirmation creation of your structure",
              body: `Dear partner, we are pleased to confirm the creation of your structure. ${structureNameReg} glass.`,
            }
          ).catch(err => console.error("邮件发送失败:", err));
        }

        setTimeout(() => navigate("/"), 500);
      })
      .catch((err) => {
        console.error("请求错误:", err);
        showToast(err?.response?.data || "添加失败,请稍后重试", false);
      });
  };

  return (
    <div>
      {/* 表单部分(补充原有表单代码) */}
      <form onSubmit={handleAddStructure}>
        {/* 表单输入框 */}
        <button type="submit">提交</button>
      </form>

      {/* Bootstrap Toast DOM结构 */}
      <div
        ref={toastRef}
        className="toast position-fixed bottom-0 end-0 m-3"
        role="alert"
        aria-live="assertive"
        aria-atomic="true"
      >
        <div className="toast-header">
          <strong className="me-auto">系统通知</strong>
          <button
            type="button"
            className="btn-close"
            data-bs-dismiss="toast"
            aria-label="Close"
          ></button>
        </div>
        <div ref={toastBodyRef} className="toast-body"></div>
      </div>
    </div>
  );
}

Express后端部分(确保返回响应)

// 示例/addStructure接口
app.post('/addStructure', async (req, res) => {
  try {
    const { asset, structure_name, email, town, ...rest } = req.body;
    // 执行数据库插入操作
    await db.query(
      'INSERT INTO structures (asset, structure_name, email, town, information, number_structure, newsletter, manage_schedule, flyer, drinks) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
      [asset, structure_name, email, town, rest.information, rest.number_structure, rest.newsletter, rest.manage_schedule, rest.flyer, rest.drinks]
    );
    // 必须返回响应,否则Axios会一直等待
    res.status(200).json({ message: '机构添加成功' });
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: '服务器内部错误' });
  }
});

邮件库引入(EmailJS为例)

在public/index.html中添加:

<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/emailjs-com@3/dist/email.min.js"></script>
<script type="text/javascript">
  (function(){
    emailjs.init("你的EmailJS用户ID"); // 在EmailJS官网获取
  })();
</script>

内容的提问来源于stack exchange,提问作者Alban Pascal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 18:01:16