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> </> ); }
问题原因
- 弹窗显示状态绑定错误:成功弹窗的
Modal使用了共用的show状态,但删除成功后已经调用setShow(false)隐藏了确认弹窗,导致成功弹窗的显示条件不满足,即使showSuccess=true也无法渲染显示。 - 组件提前重挂载:删除成功后调用
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
相关产品推荐
相关产品推荐

