【问题标题】:Multiple Nested Routes in react-router-dom v4react-router-dom v4 中的多个嵌套路由
【发布时间】:2017-08-16 12:17:33
【问题描述】:

我需要 react-router-dom 中的多个嵌套路由

我正在使用 react-router-dom 的 v4

我有我的

import { BrowserRouter as Router, Route } from 'react-router-dom';

我需要组件像这样渲染

--- Login
--- Home
    --- Page 1
    --- Page 2
    --- Page 3
--- About
--- etc

Home 组件包含 Page1、Page2 和 Page3 组件共有的 Header 组件,但在 Login 和 About 中不存在。

我的 js 代码是这样的

<Router>
    <div>
        <Route path='/login' component={Login} />
        <Home>
            <Route path='/page1' component={Page1} />
            <Route path='/page2' component={Page2} />
            <Route path='/page3' component={Page3} />
        </Home>
        <Route path='/about' component={About} />
    </div>
</Router>

我希望登录组件仅在 /login 上显示 当我请求 /page1、/page2、/page3 时,它们应该分别包含 Home 组件和该页面的内容。

我得到的是渲染的登录组件,并且在页面1的组件下方被渲染。

我很确定我遗漏了一些非常微不足道的东西或在某个地方犯了一个非常愚蠢的错误,我会很感激我能得到的所有帮助。过去两天我一直被这个问题困扰。

【问题讨论】:

  • 你需要在 Route 添加 exact 属性,该属性需要在完全匹配上显示。
  • 用 /login 尝试过,但我的 Home 组件显示在我的 Login 组件下。
  • @AdityaTalpade 也检查我的答案
  • 嘿 Aditya,你能做这件事吗?我也想做同样的事情。在我的场景中,当用户打开网站时,如果用户未登录,react 会将其重定向到登录名。登录后,我的索引页面会显示导航栏和搜索栏。现在我想在这个索引页面的正文中显示其余页面,以便所有页面共享相同的导航栏和搜索栏。如果您能帮助我,我将不胜感激。
  • 没有。我放弃了。与反应路由器 v3 一起使用。我的工作流程在处理 v4 时受到严重阻碍,不值得付出额外的努力。

标签: javascript reactjs react-router react-router-dom


【解决方案1】:

使用从 props this.props.match.path 获得的 url/path 匹配来获取设置为组件的路径。

如下定义您的主要路线

<Router>
  <div>
    <Route exact path="/" component={DummyIndex} /> {/* Note-1 */}
    <Route path="/login" component={Login} />
    <Route path="/home" component={Home} />
    <Route path="/about" component={About} />
    <Route path="/etc" component={Etc} />
  </div>
</Router>

然后在Home 组件中,定义你的路由

class Home extends Component {
  render() {
    return <div>
      <Route exact path={this.props.match.path} component={HomeDefault} />
      <Route path={`${this.props.match.path}/one`} component={HomePageOne} />
      <Route path={`${this.props.match.path}/two`} component={HomePageTwo} />
    </div>
  }
}

定义的路线如下

  • /登录
  • /家
  • /home/一个
  • /home/二
  • /关于
  • /等

如果您想在HomePageOne 中进一步嵌套路由,例如 /home/one/a/home/one/b,您可以采用相同的方法。

注意1:如果你不想进一步嵌套,只需使用propexact设置路由即可。

编辑(2017 年 5 月 15 日)

最初,我使用的是props.match.url,现在我将其更改为props.match.path

我们可以在 Route 的路径中使用props.match.path 而不是props.match.url,这样如果您在顶级路由中使用路径参数,您可以通过props.match.params 在内部(嵌套)路由中获取它。

如果你没有任何路径参数,props.match.url 就足够了

【讨论】:

  • 我收到TypeError: Cannot read property 'path' of undefined
  • 一条评论:我没有使用
    ,而是使用 来避免不必要的 html 标签。
  • @AshishKamble 如果您收到Cannot read property 'path' of undefined,则表示道具match 未定义。确保将正确的组件分配给 Route 中名为“component”的道具
  • @xiongemi 你是对的。你可以使用&lt;Switch&gt;,但它是有目的的,请确保你知道它。
  • 要摆脱Cannot read property 'path' of undefined error,你需要在参数中传递props:(props) => props.match.match.url
【解决方案2】:

在路由器 v4 中使用 Switch 组件

<Router>
<Switch>
  <Route path='/login' component={Login} />
  <Route path='/about' component={About} />
  <Home>
    <Route component={({ match }) =>
      <div>
        <Route path='/page1' component={Page1} />
        <Route path='/page2' component={Page2} />
        <Route path='/page3' component={Page3} />
      </div>
    }/>
  </Home>
</Switch>

export default class Home extends Component {
render() {
    return (
      <div className="Home">
          { this.props.children }
      </div>
    )
  }
}

我认为这段代码展示了使用组件的基本思想。

【讨论】:

  • v4 of react-router-dom 对嵌套路由 Warning: You should not use &lt;Route component&gt; and &lt;Route children&gt; in the same route; &lt;Route children&gt; will be ignored warning 抛出此警告,并且不会渲染 /page1、/page2 等下的组件
  • 是的,我看到有问题。我更改了代码,请尝试一下
  • @IgorStecyura 你有没有可能分享Home 组件的代码?
  • @RohanBüchner,Home 组件如下所示:export default class Home extends Component { render() { return (
    { this.props.children }
    )我认为这段代码展示了使用组件的基本思想
【解决方案3】:

本周我遇到了同样的问题,我认为该项目正在通过,因为所有文档、示例和视频都是针对先前版本的,而第 4 版的文档令人困惑
这就是我完成工作的方式,如果这有帮助,请告诉我

import React, { Component } from 'react';

import { BrowserRouter, Route, Switch } from 'react-router-dom';

import Root from './Root';
import Home from './Home';
import About from './About';

import './App.css';

class App extends Component {
    render() {
        return (
            <BrowserRouter>
                <div>
                    <Root>
                       <Switch>
                            <Route exact path="/" component={Home} />
                            <Route path="/home" component={Home} />
                            <Route path="/about" component={About} />
                        </Switch>
                    </Root>
                </div>
            </BrowserRouter>
        );
    }
}

export default App;

【讨论】:

  • 这种方法可行,但只是为了澄清那些不熟悉 React 继承的人:根组件需要一个包含 { props.children } 的返回值。
  • HomepageOneHomepageTwo 怎么样
【解决方案4】:

将所有子路由移动到父组件并扩展路由,如下所示。
&lt;Route path={`${match.url}/keyword`} component={Topic}/&gt;
还要检查react router training

【讨论】:

    【解决方案5】:

    使用如下:

    class App extends Component {
      render() {
        return (
          <BrowserRouter>
            <Link to='/create'> Create </Link>
            <Link to='/ExpenseDashboard'> Expense Dashboard </Link>
            <Switch>
              <Route path='/ExpenseDashboard' component={ExpenseDashboard} />
              <Route path='/create' component={AddExpensePage} />
              <Route path='/Edit' component={EditPage} />
              <Route path='/Help' component={HelpPage} />
              <Route component={NoMatch} />
            </Switch>
          </BrowserRouter>
        );
      }
    }
    

    查看更多@Switch on GitHub

    【讨论】:

      【解决方案6】:

      我遇到了同样的问题,我就这样解决了

      <BrowserRouter>
                <UserAuthProvider>
                  <Root>
                    <Switch>
                      <GuardRoute type="public" exact path="/" component={Login} />
                      <GuardRoute type="private" exact path="/home" component={Home} />
                      <GuardRoute
                        type="private"
                        exact
                        path="/home/mascotas"
                        component={Mascotas}
                      />
      
                    </Switch>
                  </Root>
                </UserAuthProvider>
              </BrowserRouter>
      

      【讨论】:

      • 英语是 Stack Overflow 上使用的语言。有一些 Stack Exchange 网站使用其他语言,但这个只有一种语言。
      猜你喜欢
      相关资源
      最近更新 更多
      热门标签