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

React中axios.delete成功后Success Modal状态丢失问题求助

问题描述

删除功能正常,但在axios.delete请求成功后设置showSuccess=true,组件重渲染时该状态自动变回false,导致成功弹窗无法显示。错误弹窗的状态变更及渲染均正常。完整组件代码如下:

import React, { useState, useEffect } from 'react';
import { getCookie } from "../../../utils/cookies";
import axios from "axios";
import Button from 'react-bootstrap/Button';
import Modal from 'react-bootstrap/Modal';
import { Trash } from 'react-bootstrap-icons';
import AlertDialog from '../../../alerts/AlertDialog';

export default function DeleteService({ fetchData, id }) {
  const [show, setShow] = useState(false);

  const handleClose = () => setShow(false);
  const handleShow = () => setShow(true);

  const [isLoading, setIsLoading] = useState(true);
  const [data, setData] = useState([]);

  // Success Dialog
  const [showSuccess, setShowSuccess] = useState(false);
  console.log(showSuccess)

  // Error Dialog
  const [showAlert, setShowAlert] = useState(false);

  // DELETE
  const deleteService = async (id: number) => {
     try {
       const JWT = await getCookie("auth");
       const { data } = await axios(
       `/api/serviceType/${id}`, {
       method: "DELETE",
       headers: {
         "Content-Type": "application/json",
         Authorization: JWT,
       },
       });

       setData(data);
       setIsLoading(false);

       // Hides Modal on submission
       setShow(false);

      // Success Alert Popup
      setShowSuccess(true);
   
     } catch (e) {
       setIsLoading(false);
       
       // Error Alert Popup
       setShowAlert(true);
     }
  };

  // Table state update on submit
  useEffect(() => {
    fetchData(data);
  }, [data]);

  // Success Alert
  if (showSuccess === true) {
    return (
      <>
        <Modal show={show} onHide={() => {setShowSuccess(false); handleClose(); }} backdrop="static">
        <Modal.Header closeButton style={{ backgroundColor: "#00E676"}}></Modal.Header>
        <AlertDialog 
          title="Success!" 
          message="Service was successfully deleted."
        />
      </Modal>
      </>
    )
  }

  if (showAlert === true) {
    return (
      <>
      <Modal show={show} onHide={() => {setShowAlert(false); handleClose(); }} backdrop="static">
        <Modal.Header closeButton style={{ backgroundColor: "#FF1744"}}></Modal.Header>
        <AlertDialog 
          title="Error Deleting Data" 
          message="There was an error deleting the Service."
        />
      </Modal>
      </>
    )
  }

  return (
    <>
      <Trash onClick={handleShow}/>

      <Modal show={show} backdrop="static" onHide={handleClose}>
        <Modal.Header closeButton>
          <Modal.Title>Delete Service</Modal.Title>
        </Modal.Header>
        <Modal.Body>
          Are you sure you want to delete this Service? This process cannot be undone.
        </Modal.Body>
        <Modal.Footer>
          <Button variant="outline-dark" onClick={handleClose}>
            Cancel
          </Button>
          <Button type="submit" variant="danger" onClick={() => deleteService(id)}>
            Delete
          </Button>
        </Modal.Footer>
      </Modal>
    </>
  );
}
问题原因
  1. 弹窗显示状态绑定错误:成功弹窗的Modal使用了共用的show状态,但删除成功后已经调用setShow(false)隐藏了确认弹窗,导致成功弹窗的显示条件不满足,即使showSuccess=true也无法渲染显示。
  2. 组件提前重挂载:删除成功后调用setData(data)触发useEffect执行fetchData(data),父组件数据更新会导致当前DeleteService组件被重新挂载,showSuccess状态被重置为初始值false。
修复方案

修改后的完整代码如下:

import React, { useState } from 'react';
import { getCookie } from "../../../utils/cookies";
import axios from "axios";
import Button from 'react-bootstrap/Button';
import Modal from 'react-bootstrap/Modal';
import { Trash } from 'react-bootstrap-icons';
import AlertDialog from '../../../alerts/AlertDialog';

export default function DeleteService({ fetchData, id }) {
  const [show, setShow] = useState(false);
  const [isLoading, setIsLoading] = useState(false);
  const [showSuccess, setShowSuccess] = useState(false);
  const [showAlert, setShowAlert] = useState(false);

  const handleClose = () => setShow(false);
  const handleShow = () => setShow(true);

  // 关闭成功弹窗并触发数据刷新
  const handleSuccessClose = () => {
    setShowSuccess(false);
    fetchData();
  };

  // 关闭错误弹窗
  const handleAlertClose = () => {
    setShowAlert(false);
  };

  const deleteService = async (id: number) => {
     setIsLoading(true);
     try {
       const JWT = await getCookie("auth");
       await axios(
         `/api/serviceType/${id}`, 
         {
           method: "DELETE",
           headers: {
             "Content-Type": "application/json",
             Authorization: JWT,
           },
         }
       );

       setShow(false);
       setShowSuccess(true);
     } catch (e) {
       setShow(false);
       setShowAlert(true);
     } finally {
       setIsLoading(false);
     }
  };

  return (
    <>
      <Trash onClick={handleShow}/>

      {/* 确认删除弹窗 */}
      <Modal show={show} backdrop="static" onHide={handleClose}>
        <Modal.Header closeButton>
          <Modal.Title>Delete Service</Modal.Title>
        </Modal.Header>
        <Modal.Body>
          Are you sure you want to delete this Service? This process cannot be undone.
        </Modal.Body>
        <Modal.Footer>
          <Button variant="outline-dark" onClick={handleClose} disabled={isLoading}>
            Cancel
          </Button>
          <Button type="submit" variant="danger" onClick={() => deleteService(id)} disabled={isLoading}>
            {isLoading ? 'Deleting...' : 'Delete'}
          </Button>
        </Modal.Footer>
      </Modal>

      {/* 成功弹窗 */}
      <Modal show={showSuccess} onHide={handleSuccessClose} backdrop="static">
        <Modal.Header closeButton style={{ backgroundColor: "#00E676"}}></Modal.Header>
        <AlertDialog 
          title="Success!" 
          message="Service was successfully deleted."
        />
      </Modal>

      {/* 错误弹窗 */}
      <Modal show={showAlert} onHide={handleAlertClose} backdrop="static">
        <Modal.Header closeButton style={{ backgroundColor: "#FF1744"}}></Modal.Header>
        <AlertDialog 
          title="Error Deleting Data" 
          message="There was an error deleting the Service."
        />
      </Modal>
    </>
  );
}

关键修改点

  • 移除冗余的data状态和useEffect,改为在成功弹窗关闭后调用fetchData(),由父组件获取最新数据,避免组件提前重挂载。
  • 成功/错误弹窗的show属性分别绑定到showSuccess/showAlert,确保状态正确时弹窗正常显示。
  • 新增独立的弹窗关闭处理方法,分离不同弹窗的逻辑。
  • 给删除按钮添加加载状态,防止重复点击。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 23:25:33