admin管理员组

文章数量:1418419

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} ponent={AppContainer}>
    <Route path="view-1"
        onEnter={ view1onEnter }
        onLeave={ view1onLeave }
        ponent={ View1 }
        canNavigate={ false }
    />
    <Route path="view-2"
        onEnter={ view2onEnter }
        onLeave={ view2onLeave }
        ponent={ 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?

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} ponent={AppContainer}>
    <Route path="view-1"
        onEnter={ view1onEnter }
        onLeave={ view1onLeave }
        ponent={ View1 }
        canNavigate={ false }
    />
    <Route path="view-2"
        onEnter={ view2onEnter }
        onLeave={ view2onLeave }
        ponent={ 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?

Share Improve this question asked Apr 9, 2016 at 9:31 KirilKiril 2,9631 gold badge34 silver badges41 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 2

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.

本文标签: javascriptReactrouter prevent navigation to target routeStack Overflow