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 然后呈现一个导航栏和一个新的 Route,它将匹配我们刚刚呈现的导航栏中的任何链接(因为链接链接到 /topics/${id} 并且路由与 /topics/:topicId 匹配)。这意味着如果我们单击主题组件中的任何链接。
需要注意的是,仅仅因为我们匹配了另一个 Route 组件,这并不意味着之前匹配的 Route 仍然不会被渲染。这让很多人感到困惑。请记住,将 Route 视为渲染另一个组件或 null。你认为在 React 中嵌套普通组件的方式可以直接应用于嵌套路由。
在这一点上,我们进展顺利。如果出于某种原因,您的团队中另一个不熟悉 React Router 的成员决定将 /topics 更改为 /concepts 怎么办?他们可能会前往主 App 组件并更改 Route
// <Route path='/topics' component={Topics} />
<Route path='/concepts' component={Topics} />
问题是,这完全破坏了应用程序。在 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 ...
}
请注意,path 包含 URL 参数,而 url 只是完整的 URL。这就是为什么一个用于 Links 而另一个用于 Routes。
当您创建嵌套链接时,您不想使用 URL 参数。您希望用户直接访问 /topics/react-router/url-parameters。这就是为什么 match.url 更适合嵌套的 Links。但是,当您使用 Route 匹配某些模式时,您希望包含 URL 参数 - 这就是 match.path 用于 nested Routes 的原因>.