React-router:阻止导航到目标路由

Kir*_*ril 7 javascript browser-history reactjs react-router

我正在使用带有历史记录的react-router useQueries(createHashHistory)(),我想要根据路由配置阻止导航到多个路由.
所以路由配置如下:

<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>
Run Code Online (Sandbox Code Playgroud)

所以我们假设我正在进行#/view-2并调用类似的动作history.push({pathname: '/view-1'});.但是一旦路由view-1有一个标志canNavigate={false}- 我想阻止导航到它并显示消息而不改变散列和任何其他副作用(如调用onLeave挂钩view-2).

我正在考虑听history:

history.listenBefore((location, callback) => {
    //e.g. callback(false) to prevent navigation
})
Run Code Online (Sandbox Code Playgroud)

但我无法获得路由实例来检查canNavigate标志.
后来我发现history有一个方法match实际上根据给定的下一个路由器状态location:

history.listenBefore((location, callback) => {
    history.match(location, (error, redirectLocation, nextState) => {
        const route = _.last(nextState.routes);
        if (route.canNavigate) {
            callback();
        } else {
            callback(false);
        }
    });
})
Run Code Online (Sandbox Code Playgroud)

但问题是内部的history.match调用onLeave挂钩view-2(例如,即使用户停留在view-2视图上,也可以清除状态).

问题:是否可以view-2在历史/路由器中根据目标路由配置阻止导航而不进行任何更改?

Den*_*ush 2

一旦你调用了history.push,React就无法阻止导航。

您应该使用自定义服务封装历史记录服务,该服务将检查是否可以导航,如果可以则调用history.push。否则阻止导航并保持状态。