首页 > 解决方案 > React 路由器 - 使用子路由导航内页

问题描述

我正在使用反应路由在页面之间导航。该导航具有子链接,父链接 1 父链接 2 a。父 1/子链接 1 b. 父1/子链接2

一个。父 2/子链接 1 b. parent2/child 链接 2 c. 父2/子链接3

如何在 react-router 中实现此导航。请参阅此帖子的附件图片,以清楚了解我的查询。

在此处输入图像描述

标签: reactjsreact-router

解决方案


class App extends Component {
  render() {
    return (
      <Router>
        <div style={{width: 1000, margin: '0 auto'}}>
          <ul>
            <li><Link to='/'>Home</Link></li>
            <li><Link to='/topics'>Topics</Link></li>
          </ul>

          <hr />

          <Route exact path='/' component={Home} />
          <Route path='/topics' component={Topics} />
        </div>
      </Router>
    )
  }
}  

此时, ” 包含一个路径和一个组件。当您的应用程序的当前位置与路径匹配时,将呈现该组件。如果没有,Route 将呈现 null。”

function Topics () {
  return (
    <div>
      <h1>Topics</h1>
      <ul>
        {topics.map(({ name, id }) => (
          <li key={id}>
            <Link to={`/topics/${id}`}>{name}</Link>
          </li>
        ))}
      </ul>

      <hr />

      <Route path={`/topics/:topicId`} component={Topic}/>
    </div>
  )
}  

当我们转到/topics时,会呈现 Topic 组件。然后主题呈现一个导航栏和一个新路由,它将匹配我们刚刚呈现的导航栏中的任何链接(因为链接链接到 /topics/${id}并且路由匹配/topics/:topicId)。这意味着如果我们单击主题组件中的任何链接。

需要注意的是,仅仅因为我们匹配了另一个 Route 组件,这并不意味着之前匹配的 Route 仍然不会被渲染。这让很多人感到困惑。请记住,将 Route 视为渲染另一个组件或 null。你认为在 React 中嵌套普通组件的方式可以直接应用于嵌套 Routes

在这一点上,我们进展顺利。如果出于某种原因,您的团队中另一个不熟悉 React Router 的成员决定将 /topics 更改为 /concepts 怎么办?他们可能会前往主 App 组件并更改 Route

// <Route path='/topics' component={Topics} />
<Route path='/concepts' component={Topics} />  

问题是,这完全破坏了应用程序。在主题组件内部,我们假设路径以 /topics 开头,但现在它已更改为 /concepts。我们需要的是一种让主题组件接收初始路径作为道具的方法。这样,无论是否有人更改父 Route,它都将始终正常工作。对我们来说好消息是 React Router 正是这样做的。每次使用 React Router 渲染组件时,都会向该组件传递三个 props——位置、匹配和历史记录。我们关心的是匹配。match 将包含有关 Route 如何匹配的信息(正是我们需要的)。具体来说,它有两个我们需要的属性,path 和 url。这些非常相似,这就是文档描述它们的方式 -

path - 用于匹配的路径模式。用于构建嵌套路由

url - URL 的匹配部分。用于构建嵌套链接

假设我们正在使用一个具有嵌套路由的应用程序,并且当前 URL 是/topics/react-router/url-parameters。

如果我们要在最嵌套的组件中记录match.path 和 match.url,这就是我们会得到的。

render() {
  const { match } = this.props // coming from React Router.

  console.log(match.path) // /topics/:topicId/:subId

  console.log(match.url) // /topics/react-router/url-parameters

  return ...
}  

请注意,路径包含 URL 参数,而url只是完整的 URL。这就是为什么一个用于Links而另一个用于Routes的原因。

创建嵌套链接时,您不想使用 URL 参数。您希望用户从字面上转到/topics/react-router/url-parameters。这就是为什么match.url更适合嵌套的Links。但是,当您使用Route匹配某些模式时,您希望包含 URL 参数 - 这就是match.path用于嵌套 Routes的原因。


推荐阅读