listenBefore/setRouteLeaveHook not being called
See original GitHub issueI’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
}
...
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/3793listenBefore
: this is not being called at all with default setup. I’m usingbrowserHistory
that is shipped with react-router (importing likerequire('react-router/lib/browserHistory')
)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 getlistenBeforeUnload
working after usinguseBeforeUnload
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:
- Created 7 years ago
- Comments:11 (2 by maintainers)
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.
@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 @mjacksonEssentially changing “confirming navigation” example to:
Breaks the navigation. If
test
function was to returnundefined
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.