39

I'm using React js. I need to detect page refresh. When user hits refresh icon or press F5, I need to find out the event.

I tried with stackoverflow post by using javascript functions

I used javascript function beforeunload still no luck.

onUnload(event) { 
  alert('page Refreshed')
}

componentDidMount() {
  window.addEventListener("beforeunload", this.onUnload)
}

componentWillUnmount() {
   window.removeEventListener("beforeunload", this.onUnload)
}

here I have full code on stackblitz

Maria Jeysingh Anbu
  • 2,872
  • 2
  • 31
  • 52

6 Answers6

24

Place this in the constructor:

if (window.performance) {
  if (performance.navigation.type == 1) {
    alert( "This page is reloaded" );
  } else {
    alert( "This page is not reloaded");
  }
}

It will work, please see this example on stackblitz.

Will
  • 672
  • 9
  • 21
20

If you're using React Hook, UseEffect you can put the below changes in your component. It worked for me

useEffect(() => {
    window.addEventListener("beforeunload", alertUser);
    return () => {
      window.removeEventListener("beforeunload", alertUser);
    };
  }, []);
  const alertUser = (e) => {
    e.preventDefault();
    e.returnValue = "";
  };
pradeepradyumna
  • 695
  • 9
  • 33
11

Your code seems to be working just fine, your alert won't work because you aren't stopping the refresh. If you console.log('hello') the output is shown.

UPDATE ---

This should stop the user refreshing but it depends on what you want to happen.

componentDidMount() {
    window.onbeforeunload = function() {
        this.onUnload();
        return "";
    }.bind(this);
}
Will
  • 672
  • 9
  • 21
10

Unfortunately currently accepted answer cannot be more considered as acceptable since performance.navigation.type is deprecated

The newest API for that is experimental ATM. As a workaround I can only suggest to save some value in redux (or whatever you use) store to indicate state after reload and on first route change update it to indicate that route was changed not because of refresh.

Rvach.Flyver
  • 164
  • 1
  • 7
  • didn't think redux survived a browser refresh – nrmad Jul 19 '21 at 10:49
  • It is not, but it could be used to identify route change by setting some global state flag. In case the flag has default value, it means we are in state after refresh, otherwise it is the route change. – Rvach.Flyver Jul 20 '21 at 09:27
9

It is actually quite straight-forward, this will add the default alert whenever you reload your page.

Functional Component

useEffect(() => {
    window.onbeforeunload = function() {
        return true;
    };

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

Class Component

componentDidMount(){
    window.onbeforeunload = function() {
        return true;
    };
}

componentDidUnmount(){
    window.onbeforeunload = null;
}

You can put validation to only add alert whenever the condition is true.

Functional Component

useEffect(() => {
    if (condition) {
        window.onbeforeunload = function() {
            return true;
        };
    }

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

Class Component

componentDidMount(){
    if (condition) {
        window.onbeforeunload = function() {
            return true;
        };
    }
}

componentDidUnmount(){
    window.onbeforeunload = null;
}
Michael Harley
  • 628
  • 1
  • 6
  • 16
  • How can i use this code in react.js class component ? – Mayur Vaghasiya Mar 10 '21 at 09:23
  • 1
    @Mayur Vaghasiya, you can use `componentDidMount` and `componentDidUnmount` function for the Class Component. The one on my useEffect is for `componentDidMount` and the one on my useEffect's return is for `componentDidUnmount`. I'll edit my answer later when I have the time. – Michael Harley Mar 11 '21 at 12:44
  • Is there any way to modify the message in the prompt that comes after reloading? – Dhiraj Sharma May 06 '21 at 06:34
4

If you are using either REDUX or CONTEXT API then its quite easy. You can check the REDUX or CONTEXT state variables. When the user refreshes the page it reset the CONTEXT or REDUX state and you have to set them manually again. So if they are not set or equal to the initial value which you have given then you can assume that the page is refreshed.

Nitesh Malviya
  • 704
  • 7
  • 16
  • Initially I found this approach useful, but then I found it had created a bug for me, so now what I'm doing is storing a string prop called currentPage in one of my redux reducers from my componentDidMount but checking its value before setting it, to ensure that the previous page was a different page and not simply a reload. Time will tell if this is a good approach or not – Joseph Beuys' Mum Sep 25 '20 at 09:17