【问题标题】:How can I redirect to an absolute path with react-router v4?如何使用 react-router v4 重定向到绝对路径?
【发布时间】:2017-07-19 17:29:25
【问题描述】:

我有一个巨大的 Django 网络应用程序,其中一个模块(“仪表板”)是用节点编写的并做出反应。用户登录由 Django 模块处理。

用户应该登录到主应用程序才能访问反应仪表板,这部分工作 - 代码从浏览器获取用户会话,并且只有在存在时才会呈现内容。

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

我在 BrowserRouter 组件中使用基本名称来使用相对于 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' 属性并将其添加到每个后续路由中,但是如果这个模块最终变得更大,它将使路由变得更加困难。有没有更好的方法来做到这一点?

【问题讨论】:

    标签: reactjs react-router-v4


    【解决方案1】:

    很遗憾,这是不可能的。如果您使用的是基本名称,它将在创建 href 之前添加到每个路径的基本名称中。这发生在createBrowserHistory 中的history 模块中的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 设为常量,并将其添加到你的每条路线的路径前面。

    很遗憾,没有ignoreBasename 选项可用于&lt;Route /&gt;&lt;Redirect /&gt;,尽管它是可以实现的。

    【讨论】:

    • 附带说明一下,我可以通过对history/createBrowserHistory.jsreact-router/Redirect.js 进行一些修补来实现ignoreBasename 选项。这让我很感兴趣,所以我正在考虑制作一个功能并请求将其添加到更高版本中。
    • 有什么消息吗?该选项将非常有用。
    • 很抱歉,我决定不再继续这样做了。我正在为 React-Router 的 v4 browserRouter 执行此操作,它在第 19 行实例化历史模块。为避免createBrowserHistory.js 的第 77 行产生的警告,您需要在 createBrowserHistory.js 中添加一个标志,将其包含在 browserRouter 中,然后实现ignoreBasename 功能,这并不难,但您需要跨不同路由器类型复制更改,它会影响多个库。我觉得这个问题还不够普遍,不足以保证进行更改。
    【解决方案2】:

    正如凯尔的回答中提到的,没有办法必须使用绝对网址或忽略基本名称;但是,如果您想要或“需要”从组件的渲染方法运行重定向,您可以创建自己的超轻“绝对重定向”组件,这是我的:

    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 } />
    
        ...
    
    }
    

    希望这会有所帮助:)

    【讨论】:

      【解决方案3】:

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

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

      导航到不同的站点正在使用:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-04-05
        • 1970-01-01
        • 1970-01-01
        • 2019-07-01
        • 2017-02-20
        • 1970-01-01
        • 2020-09-26
        • 2017-11-23
        相关资源
        最近更新 更多