Home > Software design >  Setting state to true inside a try {} block, but state automatically switching back to false on comp
Setting state to true inside a try {} block, but state automatically switching back to false on comp

Time:11-09

I am trying to implement a Success Confirmation popup modal after a successful axios.delete call.

The delete is working and even console.log() works inside of my conditional rendering but I've noticed that my initial state is false, on successful delete (inside of my try block) the state changes to true but then once the component re-renders it chnages back to false, causing my popup modal to not render.

I'm not sure if the try block is the issue or the way I'm trying to render the popup modal.

Initial State

const [showSuccess, setShowSuccess] = useState(false);

axios request

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);

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

The alert state change inside of the catch block works as needed!

Conditional Render

// 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 Type 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>
    </>
  );

The error modal and confirm modal work, but the success modal is not.

Entire Component

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>
    </>
  );
}

CodePudding user response:

You set show to false immediately before setting showSuccess to true. Remember all of your modals rely on show.

You already have separate variables to show the other modals, so why not use them?

Change show to showDelete (for clarity) and change your return to:

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

      <Modal show={showDelete} 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={showSuccess} onHide={() => {setShowSuccess(false); handleClose(); }} backdrop="static">
        <Modal.Header closeButton style={{ backgroundColor: "#00E676"}}></Modal.Header>
        <AlertDialog 
          title={"Success!"} 
          message={"Service was successfully deleted."}
        />  
      </Modal>

      <Modal show={showAlert} 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>
    </>
  );

Delete both if statements.


If that's too cluttered for you, you can put the modals into variables for organization.

const deleteModal = 
      <Modal show={showDelete} backdrop="static" onHide={handleClose}>
          ...
      </Modal>

const successModal = 
      <Modal show={showSuccess} onHide={() => {setShowSuccess(false); handleClose(); }} backdrop="static">
          ...
      </Modal>

const alertModal = 
      <Modal show={showAlert} onHide={() => {setShowAlert(false); handleClose(); }} backdrop="static">
          ...
      </Modal>

return (
    <>
      <Trash onClick={handleShow}/>
      {deleteModal}
      {successModal}
      {alertModal}
    </>
  );

CodePudding user response:

In your deleteService function you call setShow(false); which causes the modal to be hidden, because you pass "show" as prop to your Modal even if showSuccess is true.

The confusion is created by variable name "show" that doesn't tell anything specific about its value, so at the end is used incorrectly

  • Related