question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

listenBefore/setRouteLeaveHook not being called

See original GitHub issue

I’m trying to implement “ConfirmingNavigation” functionality and having trouble following current documentation. Speaking of these 2 pages in particular:

https://github.com/reactjs/react-router/blob/master/docs/guides/Histories.md https://github.com/reactjs/react-router/blob/master/docs/guides/ConfirmingNavigation.md

It looks there are 2 ways of achieving essentially the same thing: using setRouteLeaveHook or using listenBefore method of History. It looks to me (correct me if I’m wrong) that neither work out of the box. Consider a case where you have a deeply nested form that doesn’t have current route in props, but needs to prevent navigation. For simplicity router is accessed via context, essentially having this:

...
componentDidMount: function() {
  var test = function() { console.log('hello'); };
  this.context.router.listenBefore(test); // or setRouteLeaveHook
}
...
  1. setRouteLeaveHook: because the component is deeply nested, it’s hard to get a hold of current route, and you need to pass a route object, not just a pathname. This makes using this method a bit complicated. In my case this method didn’t invoke the callback, which might be related to https://github.com/reactjs/react-router/issues/3793
  2. listenBefore: this is not being called at all with default setup. I’m using browserHistory that is shipped with react-router (importing like require('react-router/lib/browserHistory'))
  3. listenBeforeUnload: when trying to use History directly, you need to use specific version (2.x). Maybe this needs to be mentioned in the documentation. I tried to go through API Docs of History and make it work with new version only to see an error after I set everything up correctly. With History 2.x I managed to get listenBeforeUnload working after using useBeforeUnload wrapper. listenBefore still didn’t work at all. Perhaps History instance needs to be wrapped in some of those “enhancer” middlewares, it’s not clearly documented at this point.

Can you please point me at the documentation or an example where this functionality is implemented with current react-router and some version of History? SO has no issues regarding this, and following examples gets me nowhere with callbacks not being called.

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:11 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
livemixlovecommented, Feb 14, 2017

Oh, now I see, I didn’t fully understand what passing down the route object meant. Not sure if this is the recommended way, but I found that that route object on child routes needs to be used like:

router.setRouteLeaveHook(route.childRoutes[0], this.routerWillLeave.bind(this))

Seems a bit messy, but it’s now working.

1reaction
suprMaxcommented, Sep 8, 2016

@taion I managed to isolate the issue. It is due to a strange behavior in History. Apparently if you have listenBefore hook set before router starts, and this hook confirms that navigation is allowed, setRouteLeaveHook is never being called. I would assume from the documentation that every hook is called and only if every hook passes, the navigation occurs. I think there supposed to be some sort of an error for this case. This took me a long time to figure out. cc @mjackson

Essentially changing “confirming navigation” example to:

....
function test() { return true; }
browserHistory.listenBefore(test)

render((
  <Router history={withExampleBasename(browserHistory, __dirname)}>
    //...
  </Router>
), document.getElementById('example'))

Breaks the navigation. If test function was to return undefined everything works as expected. This becomes an issue for CoffeeScript users with implicit return statements. I think this should to be mentioned in the documentation.

Read more comments on GitHub >

github_iconTop Results From Across the Web

listenBefore/setRouteLeaveHook not being called · Issue #3797
I'm trying to implement "ConfirmingNavigation" functionality and having trouble following current documentation. Speaking of these 2 pages ...
Read more >
Detecting user leaving page with react-router - Stack Overflow
Using only setRouteLeaveHook was not enough. For some reason, the URL was changed although the page remained the same when 'back button' was ......
Read more >
Adding an 'unsaved changes' prompt to a Redux form - Medium
I'm adding this prompt in my React project to a Redux Form. We're already working with the reduxForm HOC (higher-order component) and also...
Read more >
[Solved]-Detecting user leaving page with react-router-Reactjs
Using only setRouteLeaveHook was not enough. For some reason, the URL was changed although the page remained the same when 'back button' was...
Read more >
react-router prompt
React Router core has a component called Prompt. The purpose of this component is to show a dialog to the user during a...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found