I'm using react-router with history useQueries(createHashHistory)()
and I have several routes that I want to prevent navigation to based on route's configuration.
So routes config is like:
<Route path="/" name={RouteNames.APP} component={AppContainer}>
<Route path="view-1"
onEnter={ view1onEnter }
onLeave={ view1onLeave }
component={ View1 }
canNavigate={ false }
/>
<Route path="view-2"
onEnter={ view2onEnter }
onLeave={ view2onLeave }
component={ View2 }
canNavigate={ true }
/>
...
</Route>
So let's assume I'm on #/view-2
and call an action like history.push({pathname: '/view-1'});
. But as soon as route view-1
has a flag canNavigate={false}
- I want to prevent navigation to it and show a message without changing a hash and any other side effects (like calling onLeave
hook of view-2
).
I was thinking about listening to history
:
history.listenBefore((location, callback) => {
//e.g. callback(false) to prevent navigation
})
but I can't get the route instance to check canNavigate
flag.
Later I've found out that history
has a method match
which actually gets next router state based on the given location
:
history.listenBefore((location, callback) => {
history.match(location, (error, redirectLocation, nextState) => {
const route = _.last(nextState.routes);
if (route.canNavigate) {
callback();
} else {
callback(false);
}
});
})
but the problem is that history.match
calls onLeave
hook for view-2
inside (which may, for example, clear state even though the user stays on the view-2
view).
The question: is it possible to prevent navigation from view-2
without any changes at all in history/router and making this decision based on target route configuration?
React cannot prevent the navigation once you've called history.push.
You should encapsulate the history service with a custom one that will check whether it is possible to navigate and if it is then call history.push. otherwise prevent the navigation and keep the state.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With