React | How to detect Page Refresh (F5)
Asked Answered
A

7

57

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

Affective answered 25/4, 2018 at 15:25 Comment(3)
Why not just check for e.keyCode === 116, which is the F5 key? Here is an example of how to do that: https://mcmap.net/q/93241/-how-to-handle-the-onkeypress-event-in-reactjsMcneese
There may be two scenarios browser refresh button click and F5 pressAffective
Your code works fineLackey
S
27

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.

Sowder answered 25/4, 2018 at 16:5 Comment(9)
But there is the problem. It is getting triggered even page changing. not only page refresh. I need only page refreshAffective
Just change the content of conditionsSowder
I'm using react router. when I switch menu It is getting triggeredAffective
Please see the alert text, if page refresh an alert "This page is reloaded" will be triggered , else another alert "this page is not reloaded" will be triggered. So you can use just the first conditionSowder
@MariaJeysinghAnbu is saying corrent it trigger the refresh alert even route changed in IE. In IE even if user changes route its values is 1 but in chrome its working differentlyFosterfosterage
will this work if the user clicks on the refresh button instead F5?Backspin
How do you do something AFTER refresh has complete?Serve
This is deprecated now. PerformanceNavigationTiming should be used instead.Squally
Performance.navigation is deprecated, see Performance.navigation on MDNMawkin
G
38

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 = "";
  };
Graphite answered 20/12, 2020 at 13:51 Comment(1)
beforeUnload listener not only fired on refresh, but also when you are navigating with address bar, so it might fired unintentionally. Hence using return value as a flagging is wise thing to do.Makowski
S
27

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.

Sowder answered 25/4, 2018 at 16:5 Comment(9)
But there is the problem. It is getting triggered even page changing. not only page refresh. I need only page refreshAffective
Just change the content of conditionsSowder
I'm using react router. when I switch menu It is getting triggeredAffective
Please see the alert text, if page refresh an alert "This page is reloaded" will be triggered , else another alert "this page is not reloaded" will be triggered. So you can use just the first conditionSowder
@MariaJeysinghAnbu is saying corrent it trigger the refresh alert even route changed in IE. In IE even if user changes route its values is 1 but in chrome its working differentlyFosterfosterage
will this work if the user clicks on the refresh button instead F5?Backspin
How do you do something AFTER refresh has complete?Serve
This is deprecated now. PerformanceNavigationTiming should be used instead.Squally
Performance.navigation is deprecated, see Performance.navigation on MDNMawkin
G
21

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

In this answer you will find:

  1. Default usage
  2. Alert with validation

1. Default Usage

Functional Component

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

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

Class Component

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

componentDidUnmount(){
    window.onbeforeunload = null;
}

2. Alert with validation

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;
}
Griseofulvin answered 18/2, 2021 at 16:16 Comment(4)
How can i use this code in react.js class component ?Irrigation
@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.Griseofulvin
Is there any way to modify the message in the prompt that comes after reloading?Tactile
Note: If you dont return anything in the "onbeforeunload" function it will hide the confirmation dialog "Do you really want to leave this page?"Neckar
P
12

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.

Pi answered 26/12, 2018 at 15:31 Comment(3)
didn't think redux survived a browser refreshHenequen
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.Pi
@Henequen - I believe, redux can retain if you can prevent refresh.Pargeting
C
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);
}
Cult answered 25/4, 2018 at 15:36 Comment(5)
can I call any function in that onUnload function? becoz I tried it seems not working.Affective
You need to prompt the user with something that will stop the refresh. What function are you trying to place inside onUnload? I'll update my answer with an example.Cult
Only on page refresh I have to call a function like this this.props.actions.loaddata()Affective
Thank You. I think, It has been called before page load. I need after user refresh the pageAffective
Abdellatif seems to have a better solution than mine for that.Cult
P
7

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.

Pocahontas answered 8/9, 2020 at 10:45 Comment(1)
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 notNietzsche
L
2

'navigation' is deprecated, instead, add this to the constructor:

const navigationEntries = window.performance.getEntriesByType('navigation');
if (navigationEntries.length > 0 && navigationEntries[0].type === 'reload') {
 console.log("Page was reloaded");
}

Make sure to wrap it in the useEffect(). The reason for using useEffect in this case is to ensure that the code runs at the appropriate time during the component lifecycle.

When you place the code directly inside the function body without useEffect, it will be executed whenever the component function is called, which could lead to unexpected behavior.

By using useEffect with an empty dependency array ([]), you ensure that the code runs only once, after the initial render of the component. This approach is generally preferred when you want to perform initialization tasks or set up event listeners in a React component.

function MyComponent(){

   useEffect(() => {
     const navigationEntries = window.performance.getEntriesByType('navigation');
     if (navigationEntries.length > 0 && navigationEntries[0].type === 'reload') {
       console.log("Page was reloaded");
     }
   }, []);

}

export default MyComponent;
Laborsaving answered 27/5, 2023 at 14:52 Comment(2)
this triggers when you change a pageLadew
Thanks a lot!! I was searching for hours to detect if it's "reload", because it was always "navigate" and this really solved my problem!!Fancie

© 2022 - 2024 — McMap. All rights reserved.