In react-router v2.4.0
or above and before v4
there are several options
- Add function
onLeave
for Route
<Route
path="/home"
onEnter={ auth }
onLeave={ showConfirm }
component={ Home }
>
- Use function
setRouteLeaveHook
for componentDidMount
You can prevent a transition from happening or prompt the user before leaving a route with a leave hook.
const Home = withRouter(
React.createClass({
componentDidMount() {
this.props.router.setRouteLeaveHook(this.props.route, this.routerWillLeave)
},
routerWillLeave(nextLocation) {
// return false to prevent a transition w/o prompting the user,
// or return a string to allow the user to decide:
// return `null` or nothing to let other hooks to be executed
//
// NOTE: if you return true, other hooks will not be executed!
if (!this.state.isSaved)
return 'Your work is not saved! Are you sure you want to leave?'
},
// ...
})
)
Note that this example makes use of the withRouter
higher-order component introduced in v2.4.0.
However these solution doesn't quite work perfectly when changing the route in URL manually
In the sense that
- we see the Confirmation - ok
- contain of page doesn't reload - ok
- URL doesn't changes - not okay
For react-router v4
using Prompt or custom history:
However in react-router v4
, its rather easier to implement with the help of Prompt
from'react-router
According to the documentation
Prompt
Used to prompt the user before navigating away from a page. When your
application enters a state that should prevent the user from
navigating away (like a form is half-filled out), render a <Prompt>
.
import { Prompt } from 'react-router'
<Prompt
when={formIsHalfFilledOut}
message="Are you sure you want to leave?"
/>
message: string
The message to prompt the user with when they try to navigate away.
<Prompt message="Are you sure you want to leave?"/>
message: func
Will be called with the next location and action the user is
attempting to navigate to. Return a string to show a prompt to the
user or true to allow the transition.
<Prompt message={location => (
`Are you sure you want to go to ${location.pathname}?`
)}/>
when: bool
Instead of conditionally rendering a <Prompt>
behind a guard, you
can always render it but pass when={true}
or when={false}
to
prevent or allow navigation accordingly.
In your render method you simply need to add this as mentioned in the documentation according to your need.
UPDATE:
In case you would want to have a custom action to take when user is leaving page, you can make use of custom history and configure your Router like
history.js
import createBrowserHistory from 'history/createBrowserHistory'
export const history = createBrowserHistory()
...
import { history } from 'path/to/history';
<Router history={history}>
<App/>
</Router>
and then in your component you can make use of history.block
like
import { history } from 'path/to/history';
class MyComponent extends React.Component {
componentDidMount() {
this.unblock = history.block(targetLocation => {
// take your action here
return false;
});
}
componentWillUnmount() {
this.unblock();
}
render() {
//component render here
}
}