Home  >  Q&A  >  body text

How to use custom alert in React to switch tabs?

I am creating a react-router alert, so here I want to apply an alert message when you want to switch from one tab to another. I've applied the alert attribute because I created a function confirmSwitchTab but it doesn't work. How can I make that prompt so that when I want to switch from one tab to another in each route, it displays the message.

import { React, useState } from "react";
import { Link } from "react-router-dom";
import LoadingBar from "react-top-loading-bar";
import { useNavigate } from "react-router-dom";

export default function Demo() {
  const [progress, setProgress] = useState(0);
  const navigate = useNavigate();

  function confirmSwitchTab() {
    //Prompt the user with a confirm message.
    var result = confirm("Are you sure you want to switch tabs?");
    //If the user confirms, return true, else return false.
    if (result) {
      return true;
    } else {
      return false;
    }
  }

  const onClick = () => {
    const userConfirmsSwith = confirmSwitchTab()
    if (userConfirmsSwith) navigate("/")
    // else you don't do anything.
  }

  return (
    <>
      <LoadingBar
        color="blue"
        progress={progress}
        onLoaderFinished={() => setProgress(0)}
        waitingTime={800}
        loaderSpeed={100}
        height={4}
      />
      <ul
        style={{
          display: "flex",
          justifyContent: "space-around",
          listStyle: "none"
        }}
      >
        <li>
          <Link
            to="/"
            onClick={() => {
              onClick();
              setTimeout(() => setProgress(100), 500)
            }}
          >
            Home
          </Link>
        </li>
        <li>
          <Link
            to="/about"
            onClick={() => {
              onClick();
              setTimeout(() => setProgress(100), 500)
            }}
          >
            About
          </Link>
        </li>
      </ul>
    </>
  );
}

P粉744831602P粉744831602281 days ago348

reply all(2)I'll reply

  • P粉564301782

    P粉5643017822024-02-04 15:50:08

    It doesn't work because the code doesn't prevent the default link action from happening. When a link is clicked, the navigation action takes effect immediately while the attached onClick handler is running other logic.

    Click handlers should also consume the click event object and call preventDefault on it to stop navigation operations from occurring.

    export default function Demo() {
      const [progress, setProgress] = useState(0);
      const navigate = useNavigate();
    
      function confirmSwitchTab() {
        //Prompt the user with a confirm message.
        return confirm("Are you sure you want to switch tabs?");
      }
    
      const clickHandler = (target = "/") => (e) => {
        e.preventDefault(); // <-- halt link navigation
    
        setTimeout(() => setProgress(100), 500);
    
        if (confirmSwitchTab()) {
          navigate(target);
        }
        // else you don't do anything.
      }
    
      return (
        <>
          
          
    • Home
    • About
    ); }

    reply
    0
  • P粉914731066

    P粉9147310662024-02-04 12:11:39

    I believe there is a misunderstanding here about how onLeave works :-)

    Returning true will not "confirm the leave operation". Regardless, the request for leave will be confirmed. The onLeave attribute will simply take a function and trigger it when you leave the page. This function can be a hint, like here, but the returned value will not be used.

    What you want to achieve must be completed before the page actually leaves. Somewhere in your application you should have a navigation menu where you can actually change pages by clicking a button (usually using

    history.push("My/New/Path")

    )

    Now this is where you will use the function.

    Assuming you have something similar

    You want to call the confirmSwitchTab function in this callback.

    You can change it to something like

    const onClick = () => {
      const userConfirmsSwith = confirmSwitchTab()
      if (userConfirmsSwith) history.push('home')
      // else you don't do anything.
    }
    
    

    Hope this helps, please let me know if my question is wrong!

    cheers

    After editing the question

    Try this:

    import { React, useState } from "react";
    import LoadingBar from "react-top-loading-bar";
    import { useNavigate } from "react-router-dom";
    export default function Demo() {
      const [progress, setProgress] = useState(0);
      const navigate = useNavigate();
      function confirmSwitchTab() {
        //Prompt the user with a confirm message.
        var result = confirm("Are you sure you want to switch tabs?");
        //If the user confirms, return true, else return false.
        if (result) {
          return true;
        } else {
          return false;
        }
      }
      const onClick = (path) => {
        setTimeout(() => setProgress(100), 500)
        const userConfirmsSwith = confirmSwitchTab()
        if (userConfirmsSwith) navigate(path)
        // else you don't do anything.
      }
      return (
        <>
           setProgress(0)}
            waitingTime={800}
            loaderSpeed={100}
            height={4}
          />
          
    ); }

    reply
    0
  • Cancelreply