Response-router v4: prevent navigation with custom host instead of request

In react-router

v3, I used router.setRouteLeaveHook

to check if the form has unsaved changes, and if so, revert false

to prevent transition. Then I would display a custom modal download dialog with three buttons: Save Changes, Discard Changes, and Stay Here.

I cannot use the react-router

v4 component Prompt

to do this because it is not possible to customize the buttons specified in the browser confirmation dialog. They seem to have gotten rid of any way to undo the transition in favor of only allowing to ask the user to approve the transition in a browser confirmation dialog.

I tried looking at the code Prompt

, but it just passes the dialog messagehistory

, so give me any idea on how to set up a v3 style search route.

Perhaps this is possible, or have the developers react-router

deliberately decided to remove this feature for some reason?


source to share

2 answers

According to the history package docs, you can replace window.confirm

with anything:

By default, window.confirm is used to display a prompt to the user. If you need to override this behavior (or if you are using createMemoryHistory, which does not assume a DOM environment), provide the getUserConfirmation function when creating the history object.

So, if you want to use your own dialog, something like this should see you:

const history = createHistory({
  getUserConfirmation(message, callback) {
      .then(result => callback(result === 'The YES button'))


This means that whatever message getUserConfirmation

you set is set for the entire session, but you can abstract it down to a nav blocking layer that contains additional information for your dialog, eg. title, button text, colors, etc.

Alternatively, you can grab the argument message

and use it to configure the dialog, although that might smell a little. But it's not a perfect system, so whatever you do is likely to be a bit of a hack.

React Router v4 allows you to pass this method when you create your router (see here ):

<BrowserRouter getUserConfirmation={yourConfirmationFunction} />




I do not think that's possible. react-router-v4 uses the history package which uses the HTML5 history api in turn. The history api only notifies you when you hit the back button (onpopstate). If you think about it, it makes a lot of sense as you don't want the site to prevent you from navigating between pages.

The best you can do is the onbeforeunload event window , which creates an invitation to request a request from the user, but this is exactly what kind of response mechanism gives you the opportunity to use.

You can get some of the functionality you want with the built-in intrusion defense interaction history object, and this way you can add your own behavior. But there is a caveat, this will only work when you react to your router <Link />

and friends, so you won't be able to intercept updates and other things that you might need.

If you'd like to go this route, let me know that I can give you some ideas or code examples on how this works, and I'll update my answer.



All Articles