React 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 组件内部,我们假设路径以 /topics 开头,但现在它已更改为 /concepts。我们需要的是一种让 Topics 组件接收任何初始路径作为props的方法。这样,无论是否有人更改父 Route,它都将始终有效。对我们来说好消息是 React Router 正是这样做的。每次使用 React Router 渲染组件时,都会向该组件传递三个 props - location、match 和 history。我们关心的是匹配。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 ...
}
请注意,path包含 URL 参数,而url只是完整的 URL。这就是为什么一个用于Links而另一个用于Routes。
创建嵌套链接时,您不想使用 URL 参数。您希望用户直接转到/topics/react-router/url-parameters。这就是match.url更适合嵌套Links 的原因。但是,当您将某些模式与Route匹配时,您希望包含 URL 参数 - 这就是match.path用于嵌套 Routes 的原因。