I\'m using Material-ui\'s Tabs, which are controlled and I\'m using them for (React-router) Links like this:
For giving warning on the press of browser back in react functional components. do the following steps
const [isBackButtonClicked, setBackbuttonPress] = useState(false);
window.history.pushState(null, null, window.location.pathname);
window.addEventListener('popstate', onBackButtonEvent);
define onBackButtonEvent Function and write logic as per your requirement.
const onBackButtonEvent = (e) => {
e.preventDefault();
if (!isBackButtonClicked) {
if (window.confirm("Do you want to go to Test Listing")) {
setBackbuttonPress(true)
props.history.go(listingpage)
} else {
window.history.pushState(null, null, window.location.pathname);
setBackbuttonPress(false)
}
}
}
In componentwillmount unsubscribe onBackButtonEvent Function
Final code will look like this
import React,{useEffect,useState} from 'react'
function HandleBrowserBackButton() {
const [isBackButtonClicked, setBackbuttonPress] = useState(false)
useEffect(() => {
window.history.pushState(null, null, window.location.pathname);
window.addEventListener('popstate', onBackButtonEvent);
//logic for showing popup warning on page refresh
window.onbeforeunload = function () {
return "Data will be lost if you leave the page, are you sure?";
};
return () => {
window.removeEventListener('popstate', onBackButtonEvent);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const onBackButtonEvent = (e) => {
e.preventDefault();
if (!isBackButtonClicked) {
if (window.confirm("Do you want to go to Test Listing")) {
setBackbuttonPress(true)
props.history.go(listingpage)
} else {
window.history.pushState(null, null, window.location.pathname);
setBackbuttonPress(false)
}
}
}
return (
<div>
</div>
)
}
export default HandleBrowserBackButton
I used withrouter hoc in order to get history prop and just write a componentDidMount() method:
componentDidMount() {
if (this.props.history.action === "POP") {
// custom back button implementation
}
}
Using hooks you can detect the back and forward buttons
import { useHistory } from 'react-router-dom'
const [ locationKeys, setLocationKeys ] = useState([])
const history = useHistory()
useEffect(() => {
return history.listen(location => {
if (history.action === 'PUSH') {
setLocationKeys([ location.key ])
}
if (history.action === 'POP') {
if (locationKeys[1] === location.key) {
setLocationKeys(([ _, ...keys ]) => keys)
// Handle forward event
} else {
setLocationKeys((keys) => [ location.key, ...keys ])
// Handle back event
}
}
})
}, [ locationKeys, ])
This is a bit old question and you've probably already got your answer, but for people like me who needed this, I'm leaving this answer.
Using react-router made the job simple as such:
import { browserHistory } from 'react-router';
componentDidMount() {
super.componentDidMount();
this.onScrollNearBottom(this.scrollToLoad);
this.backListener = browserHistory.listen(location => {
if (location.action === "POP") {
// Do your stuff
}
});
}
componentWillUnmount() {
super.componentWillUnmount();
// Unbind listener
this.backListener();
}
Version 3.x of the React Router API has a set of utilities you can use to expose a "Back" button event before the event registers with the browser's history. You must first wrap your component in the withRouter() higher-order component. You can then use the setRouteLeaveHook()
function, which accepts any route
object with a valid path
property and a callback function.
import {Component} from 'react';
import {withRouter} from 'react-router';
class Foo extends Component {
componentDidMount() {
this.props.router.setRouteLeaveHook(this.props.route, this.routerWillLeave);
}
routerWillLeave(nextState) { // return false to block navigation, true to allow
if (nextState.action === 'POP') {
// handle "Back" button clicks here
}
}
}
export default withRouter(Foo);
You can use "withrouter" HOC and use this.props.history.goBack
.
<Button onClick={this.props.history.goBack}>
BACK
</Button>