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
相关产品推荐
相关产品推荐

