8

I have to show an alert on the browser back event on React js. I have tried using the addEventListener but I'm not sure where to place the code in the React page. Should I place in any life-cycle hooks or in the render? I'm not sure. Please help me out.

Ashok R Raghu
  • 101
  • 1
  • 7
  • [Some example in JS](https://stackoverflow.com/questions/2008806/how-to-detect-if-the-user-clicked-the-back-button) – Tico May 03 '19 at 09:11
  • I wanted to do it in React JS. – Ashok R Raghu May 03 '19 at 09:17
  • Exactly. You just need to adapt it. The examples are just to give you the event listener name – Tico May 03 '19 at 09:22
  • For example, I have a page called `payment.js` which renders the payment page view. So when the user tries to click browser back button on that page, can I show the alert that is written on the payment.js itself? – Ashok R Raghu May 03 '19 at 10:49

6 Answers6

6

if you use react hooks you can use useEffect hooks to do it in following step

import React, { useState, useEffect } from "react";

const [finishStatus, setfinishStatus] = useState(false);

const onBackButtonEvent = (e) => {
    e.preventDefault();
    if (!finishStatus) {
        if (window.confirm("Do you want to go back ?")) {
            setfinishStatus(true)
            // your logic
            props.history.push("/");
        } else {
            window.history.pushState(null, null, window.location.pathname);
            setfinishStatus(false)
        }
    }
}

  useEffect(() => {
    window.history.pushState(null, null, window.location.pathname);
    window.addEventListener('popstate', onBackButtonEvent);
    return () => {
      window.removeEventListener('popstate', onBackButtonEvent);  
    };
  }, []);
5

You can try this,

window.addEventListener('popstate', (event) => {
  alert("You message");
});

You can place it in componentWillMount() or componentDidMount() as per your need.

Ref

ravibagul91
  • 16,494
  • 4
  • 24
  • 45
  • I will try, but I have one more question. Will the `componeneWillMount()` or `componentDidMount()` hook be invoked on the browser back event? – Ashok R Raghu May 03 '19 at 09:27
  • @AshokRRaghu When you hit browser back button, your component will simply re-render so these methods will get execute. – ravibagul91 May 03 '19 at 09:37
  • I used but it shows only on the page load, not on the browser back button click. – Ashok R Raghu May 03 '19 at 09:37
  • For example, I have a page called `payment.js` which renders the payment page view. So when the user tries to click browser back button on that page, can I show the alert that is written on the `payment.js` itself? – Ashok R Raghu May 03 '19 at 09:50
2

check out this link How to Detect Browser Back Button event - Cross Browser

The key points there:

document.onmouseover = function() {
    //User's mouse is inside the page.
    window.innerDocClick = true;
}

document.onmouseleave = function() {
    //User's mouse has left the page.
    window.innerDocClick = false;
}

window.onhashchange = function() {
    if (window.innerDocClick) {
        //Your own in-page mechanism triggered the hash change
    } else {
        //Browser back button was clicked
    }
}

This prevents back space from being used to navigate back

 $(function(){
        /*
         * this swallows backspace keys on any non-input element.
         * stops backspace -> back
         */
        var rx = /INPUT|SELECT|TEXTAREA/i;

        $(document).bind("keydown keypress", function(e){
            if( e.which == 8 ){ // 8 == backspace
                if(!rx.test(e.target.tagName) || e.target.disabled || e.target.readOnly ){
                    e.preventDefault();
                }
            }
        });
    });
Ikechukwu
  • 1,045
  • 10
  • 21
2

Finally, I solved by myself. I have given the explanation with the code below:

First, add the below code in either componentDidUpdate or componentWillMount hook:

window.history.pushState({name: "browserBack"}, "on browser back click", window.location.href);
window.history.pushState({name: "browserBack"}, "on browser back click", window.location.href);

The reason why I'm pushing it twice is that the state will be updated only if it's pushed twice. Here's the Ref. The above code will push the current page's URL in the history on the page load.

So when the back browser button is clicked the same page will be reloaded again since the history has been manipulated by the pushState method.

Then add the following code above the pushState method:

window.addEventListener('popstate', (event) => {
  if (event.state) {
    //do your code here
  }
 }, false);

Now, when the Browser back button is clicked the above even listener will be called and since we updated the state which pushState method, the if will be true and you can do whatever you wanted to do in it.

Ashok R Raghu
  • 101
  • 1
  • 7
1

I have tried so many solutions but none of working in my case and after I find this

componentDidMount() {
        window.addEventListener("beforeunload", this._confirm);
        window.history.pushState(null, "", window.location.href);
        window.onpopstate = this._backConfirm;
    }

    componentWillUnmount() {
        window.removeEventListener("beforeunload", this._confirm);
        window.onpopstate = () => { }
    }

    _backConfirm = async () => {
        let event = window.confirm("Changes that you may not be saved.");
        if(event){
            window.history.pushState(null, "", window.location.href);
        }
    }

    _confirm = (e) => {
        var confirmationMessage = "\o/";
        e.returnValue = confirmationMessage;
        return confirmationMessage;
    }
Akshay I
  • 2,182
  • 20
  • 44
0

I found this solution and it is working fine for me.

constructor(props) {
    super(props);
    this.state = {
        onClickBackButton: false
    };
}
componentDidMount() {
   window.history.pushState(null, null, window.location.pathname);
   window.addEventListener('popstate', this.onClickBackButton);
}

onBackButtonEvent = (e) => {
    e.preventDefault();
    if (!this.onClickBackButton) {

        if (window.confirm("Do you want to go back without submitting details?")) {
            this.onClickBackButton= true;
            // your custom logic to page transition,like react-router-dom 
            history.push()
        } else {
            window.history.pushState(null, null, window.location.pathname);
            this.onClickBackButton= false;
        }
    }
}

componentWillUnmount = () => {
    window.removeEventListener('popstate', this.onClickBackButton);
}

Ref

Atit More
  • 61
  • 7