Show A Warning If Page is Closed or Refreshed in ReactJS
Asked Answered
B

3

9

My problem is that I need the user to confirm if he wants to continue to close or refresh the page. If he press No, it won't close nor refresh the page.

Please take a look at my code so far:

useEffect(() => {
    window.addEventListener("beforeunload", alertUser);
    return () => {
      window.removeEventListener("beforeunload", alertUser);
    };
  }, []);
Bergerac answered 26/8, 2021 at 4:39 Comment(3)
is your alertUser defined like this? const alertUser = (e) => { e.preventDefault(); e.returnValue = ""; };Discophile
Does this answer your question? https://mcmap.net/q/1174310/-is-there-a-function-like-componentwillunmount-that-will-fire-before-the-page-is-refreshed See the second note regarding browser support.Interosculate
@DrewReese. Can you complete it? Like there's a yes/no to select. Thank you.Bergerac
I
14

If you want to display a sort of confirmation before leaving the page then follow the beforeunload event guidelines

According to the specification, to show the confirmation dialog an event handler should call preventDefault() on the event.

However note that not all browsers support this method, and some instead require the event handler to implement one of two legacy methods:

  • assigning a string to the event's returnValue property
  • returning a string from the event handler.

To combat unwanted pop-ups, browsers may not display prompts created in beforeunload event handlers unless the page has been interacted with, or may even not display them at all.

The HTML specification states that calls to window.alert(), window.confirm(), and window.prompt() methods may be ignored during this event. See the HTML specification for more details.

I just tested this in chrome and safari and it works. I don't have a windows box, but this should cover most cases.

useEffect(() => {
  const unloadCallback = (event) => {
    event.preventDefault();
    event.returnValue = "";
    return "";
  };

  window.addEventListener("beforeunload", unloadCallback);
  return () => window.removeEventListener("beforeunload", unloadCallback);
}, []);

enter image description here enter image description here

Edit put-a-warning-if-page-refresh-in-reactjs

Interosculate answered 26/8, 2021 at 6:0 Comment(4)
Thank you. How do you customize message by the way?Bergerac
@Bergerac You can't AFAIK... likely part of the whole "...to combat unwanted pop-ups..." business. I think it is generally highly discouraged to implement nag screens like this, the focus being that you may want to clean up resources and such before the page unloads, not bother the user, or more specifically, prevent them from doing what they want in the browser.Interosculate
Hi there, I have a question. Instead of showing the browser modal can I render my custom modal component?Clarsach
@Clarsach With this method, no, you get what you get from the browser. Any more these days it is more and more recommended to adjust your app's logic to handle page reloads or navigations away without user interaction, i.e. bothering the user. If data is partially updated, i.e. dirty, either try the above to let the user know, just run some logic when the page unloads to save data or whatever, or ignore it and let the dirty pages get garbage collected.Interosculate
B
1

Alert Image

I think this answer is pretty straightforward, using useEffect() hook and window.onbeforeunload, we can do this very easily

useEffect(() => {
  window.onbeforeunload = () => true;
  ...
  return () => {
    window.onbeforeunload = null;
  };
}, []);

This will ask the user everytime before hitting reload and leaving the site.

Breaux answered 16/2 at 11:46 Comment(0)
R
-2

I think you are looking for this.

https://dev.to/eons/detect-page-refresh-tab-close-and-route-change-with-react-router-v5-3pd

Browser Refresh, Closing Tab, and back and forward buttons, are all explained.

Try this:

    useEffect(()=>{
    const unloadCallback = (event) => {      
        const e = event || window.event;
        //console.log(e)
        e.preventDefault();
        if (e) {
          e.returnValue = ''
        }
        return '';
          
    };
    
    window.addEventListener("beforeunload", unloadCallback);
    return () => {
      //cleanup function
      window.removeEventListener("beforeunload", unloadCallback);
    }
    
  },[])
Rock answered 27/12, 2022 at 17:15 Comment(1)
"try this": that is essentially the code that was posted more than a year ago.Silica

© 2022 - 2024 — McMap. All rights reserved.