React js - detect backbutton - reactjs

in reactjs don't work onbeforeunload, this code:
ComponentDidMount
window.onbeforeunload = function(e) {
return 'Are you sure you want to leave this page? You will lose any unsaved data.';
};
work with only update(F5, Ctrl + R, update) but don't work when click back button or backspace.

window.onbeforeunload will only be triggered if pressing the back button causes the browser to leave the page. If you are using hashes to track in-page state, then it's not going to do anything for you.
If that is the case, you should use window.onhashchange instead. If that's not the case, please provide more detail in your question.

Related

Confirmation on browser back button

I'm trying to achieve the following with Gatsby
The user is on a form page, if they hit the browser back button, a pop up would appear, asking if they want to leave.
If the user selects ok, then it would go back.
If the user selects cancel, then it would stay on this page
I was able to "almost" make it happen by doing the following
useEffect(() => {
const confirmExit = e => {
const leaveThisPage = window.confirm("Would you like to leave this page?")
if (!leaveThisPage) {
window.history.forward()
}
}
window.addEventListener("popstate", confirmExit)
return () => {
window.removeEventListener("popstate", confirmExit)
}
}, [])
There is one issue, if the user selects cancel, then the browser would go to the previous page. Then window.history.forward() would fire and sends them back.
I noticed that popstate event cannot be cancelled, so e.preventDefault() won't work.
Note: I also tried to test with window.onbeforeunload, but it only triggers if I close to window, or if my previous is from outside my app. Is there a work around for my issue?
Gatsby is using #reach/router under the hood, which doesn't support intercepting and preventing navigation (emphasis mine):
No history blocking. I found that the only use-case I had was preventing the user from navigating away from a half-filled out form. Not only is it pretty easy to just save the form state to session storage and bring it back when they return, but history blocking doesn’t happen when you navigate away from the app (say to another domain). This kept me from actually using history blocking and always opting to save the form state to session storage. (Source)
I second the recommendation for saving the form state using localStorage.

React route url and view changes but component function still active. Why?

I have an event function that is triggered by a button click. It's purpose is to keep the body position fixed keeping it from scrolling until you click the button again to close/toggle it off.
It works fine but, when I click to another page without toggling it off it is still active. Meaning the new page will not scroll because the body position is fixed.
I am new to React FYI
My code:
bodyFixed(event) {
document.body.classList.add('body-fixed');
}
bodyRelative(e) {
document.body.classList.remove('body-fixed');
}
I am using react-static withRouteData, RouteData, Router and I have no issues on those pages. But, on pages like an article page where the route doesn't change the same way. This is where I am seeing the problem.
Is there something I can wrap it with so that when I click to a new page it goes back to default?
Please first ask if you need more information and I will gladly add more.
Yes, you can call bodyRelative method in componentWillUnmount lifecycle hook to unset the class. Something along those lines:
componentWillUnmount() {
this.bodyRelative()
}

React-Router v4 - Prevent Transition With Function

I was able to prevent navigation as per the v4 docs, but I'm trying to hook up a function so that I can use a modal instead of an alert.
Function:
abandonForm = (route) => {
this.props.showModal('confirm');
console.log('leaving..');
}
In my page:
<NavigationPrompt when={true} message={(location) => this.abandonForm('confirm')} />
this.props.showModal('confirm') activates the modal successfully, but behind the modal the page still transitions - how can I prevent transition until a button in the modal is clicked?
Browsers only allow navigation cancellation by means of the alert box that you've mentioned. This restriction is motivated by phishing/scamming sites that try to use javascript gimmicks to create user experiences that convincingly mimic something that a browser or the OS would do (whom the user trusts). Even the format of the text shown in the alert box is crafted so that it's obvious that it originates from the site.
Of course, as long as the current URL stays within your app, you have control over it using react-router's history. For example you can do the following on navigation:
allow the navigation without confirmation
immediately navigate back to the previous location, but now with a modal on top
navigate away for real this time when the user clicks on a button in the modal.
The disadvantage of this approach (leaving out the sheer complexity of it) is that the user will not get a confirmation dialog if they try to navigate to a different site entirely.
Use:
this.unBlock = this.props.history.block((location, navigateToSelectedRoute) => {
// save navigateToSelectedRoute eg this.navigateToSelectedRoute =
// navigateToSelectedRoute;
// use this.navigateToSelectedRoute() afterwards to navigate to link
// show custom modal using setState
});
and when unblocking is done then call this.unBlock() to remove the listener.
Documentation here for history api

Alert user if the current page is temporarily left with React + React-Router

If a user attempts to change the active page (window/tab/etc) from our page to another while myState is true, we want to notify/alert the user in React JS using react-router.
I tried implementing it with the help TransitionHook and React-router's Confirming Navigation article. Though these only point out / work when user wants to close the page or reload it. Whereas I need to know when user just temporarily leaves the page without necessarily closing it.
How can I achieve this?
If by "leaving the page", you mean that the page is open, but a different window has popped up, you could consider using the document.hasFocus property. Here is one way I handled a problem that was tangentially related:
componentDidMount: function (){
setInterval(()=>{
if (document.hasFocus()){
this.checkServerState();
}
},
},

cordova back button event conflicting with browser history

I am making a cordova app, using angularjs and ui-router , the problem is when i use the cordova back button event ,my app doesn't go to the previous page, but if i comment the back button event everything works fine , i want to track the back button event but its seems not to work for me , i tried the below code also doesn't seems to help me.
document.addEventListener("backbutton", (e) => {
e.preventDefault();
e.stopPropagation();
}, true);
please help me with the issue
e.preventDefault() as it's name suggests prevents the default behaviour. Therefore you stay on the same page.
If you want to control route switches / state switches imho it's better to listen for the stateChangeStart event. There you can also prevent state changes and you have the extra bonus of knowing which state it came from and where it's going.

Resources