如何使用反应路由器 v4 重定向到绝对路径?



我有一个巨大的Django Web应用程序,其中一个模块("仪表板"(是用node和react编写的。用户登录由 Django 模块处理。

用户应该登录到主应用程序才能访问 react 仪表板,这部分有效 - 代码从浏览器获取用户会话,并且仅在有的情况下呈现内容。

如果没有会话,我现在想将用户重定向到主应用程序登录页面,但我不知道如何使用我当前的结构(以及这个血腥的 v4 路由器(来做到这一点。

我在浏览器路由器组件中使用基本名称来使用相对于 django 应用程序中仪表板路径的路由。

这是我为 app.jsx 的 JSX 想出的:

<BrowserRouter basename='/en/dashboard'>
{this.state.isAuthenticated ? (
<Paper zDepth={0} style={{ height: '100%', backgroundColor: grey900 }}>
<div style={{height: '100%'}}>
<Header />
<Switch>
<Route exact={true} path='/' component={FirstSection}/>
<Route path='/first' component={FirstSection}/>
<Route path='/second' component={SecondSection}/>
</Switch>
</div>
</Paper>
) : (
<Redirect to="/en/login"/>
)}
</BrowserRouter>

但是,它实际上重定向到en/dashboard/en/login。我相信我可以从 BrowserRouter 中删除"basename"属性并将其添加到每个后续路由中,但如果这个模块最终变得更大,它将使路由变得更加困难。有没有更好的方法可以做到这一点?

不幸的是,这是不可能的。如果您使用的是基名称,则会在创建 href 之前将其添加到每个路径的基址中。这发生在createBrowserHistoryhistory模块中使用以下函数的pushreplace方法中:

var createHref = function createHref(location) {
return basename + (0, _PathUtils.createPath)(location);
};

使用pushreplace方法。

您可以在Redirect.prototype.perform方法中找到以下代码块:

if (push) {
history.push(to);
} else {
history.replace(to);
}

以上内容可以在react-router模块的Redirect.js中找到,这是react-router-dom模块导入然后导出的内容。

为了做你想做的事情,我会把basename做一个常量,并将其添加到你每条路线的路径前面。

不幸的是,对于<Route /><Redirect />没有ignoreBasename选项,尽管它是可以实现的。

正如 Kyle 的回答中提到的,没有办法使用绝对 url 或忽略基本名称; 但是,如果您希望或"需要"从组件的 render 方法运行重定向,您可以创建自己的超轻量级"绝对重定向"组件,这是我的:

import React from 'react'
class AbsoluteRedirect extends React.Component {
constructor(props){
super(props)
}
componentDidMount(){
window.location = this.props.to
}
render(){
return null
}
}
export default AbsoluteRedirect

然后使用它其他有条件的组件,以便仅在您的验证为真时挂载它。

render(){ 
if( shouldRedirect )
return <AbsoluteRedirect to={ anotherWebsiteURL } />
...
}

希望这对:)有所帮助

你可以在没有反应路由器的情况下做到这一点:

window.location.pathname = '/en/login';

导航到其他站点正在使用:

window.location.href = 'https://stackoverflow.com';

最新更新