1. <Route>
Route组件可能是React Router中最重要的组件。它最基本的
职责是当一个location匹配到路由的path时,渲染一些UI。
思考下面的代码:
import { BrowserRouter as Router, Route } from 'react-router-dom'
<Router>
<div>
<Route exact path="/" component={Home}/>
<Route path="/news" component={NewsFeed}/>
</div>
</Router>
如果应用的location是/,那么UI层次结构就会是这样的:
<div>
<Home/>
<!-- react-empty: 2 -->
</div>
如果应用的location是/news,那么UI层次结构将会是:
<div>
<!-- react-empty: 1 -->
<NewsFeed/>
</div>
"react-empty"注释只是React的null渲染的实现细节。但就我们的目的而言,这是有益的。从技术上来说,Route组件即使它渲染为null,它也始终是“被渲染”的。一旦应用程序location与路由的路径,您的组件就会被渲染。
1.1. Route 渲染方法
<Route>有三种渲染方法:
每种方法在不同的情况下都很有用。你应该只使用这些props的其中的一种。参见下面的解释,了解为什么你有3个选项。大多数情况下,您将使用component。
1.2. Route props
三个 渲染方法将被传递到相同的三个路由props:
1.3. component
只有当location匹配时才渲染一个React组件。它将会使用route props来渲染。
<Route path="/user/:username" component={User}/>
// match参数将被从路由接收到的props解构出来
const User = ({ match }) => {
return <h1>Hello {match.params.username}!</h1>
}
当你使用component(而不是render或children,在下文)路由器使用React.createElement从给定的组件创建一个新的React元素。这意味着,如果您为component属性提供了一个内联函数,那么每次渲染您都将创建一个新的组件。这将导致现有组件的卸载和新组件的安装,而不是仅仅更新现有组件。当使用内联函数的内联函数时,使用render或children属性(下文)。
1.4. render: func
这样就可以方便地进行内联渲染和包装,而不必考虑上面所述的不需要的重新加载。
取代创建一个新的React元素是为了您使用这个属性,当location匹配的时候,你可以在一个函数中传递调用。render属性接收所有相同的route props作为component渲染属性。
// 方便的内联渲染
<Route path="/home" render={() => <div>Home</div>}/>
// 包裹/组合
const FadingRoute = ({ component: Component, ...rest }) => (
<Route {...rest} render={props => (
<FadeIn>
<Component {...props}/>
</FadeIn>
)}/>
)
<FadingRoute path="/cool" component={Something}/>
警告: <Route component> 优先于 <Route render> 所以不要在同一 <Route>上同时使用它们。
1.5. children: func
有时您需要渲染不论路径是否与location匹配。在这些情况下,您可以使用函数children属性。它的工作方式和render完全一样,只是不论匹配与否它都被调用。
children渲染属性接收所有与route props相同的属性作为component和render方法,但是当一条路由不能匹配URL时,match是null。这允许您根据路由是否匹配来动态调整UI。如果路径匹配,我们将添加一个active类:
<ul>
<ListItemLink to="/somewhere"/>
<ListItemLink to="/somewhere-else"/>
</ul>
const ListItemLink = ({ to, ...rest }) => (
<Route path={to} children={({ match }) => (
<li className={match ? 'active' : ''}>
<Link to={to} {...rest}/>
</li>
)}/>
)
这也可能对动画有帮助:
<Route children={({ match, ...rest }) => (
{/* 动画会一直渲染,所以你可以使用生命周期
让它的child进或者出 */}
<Animate>
{match && <Something {...rest}/>}
</Animate>
)}/>
警告: Both <Route component> and <Route render> 优先于 <Route children> ,所以不要在相同的 <Route>上使用超过1个。
1.6. path: string
任何可以被path-to-regexp理解有效的URL路径。path-to-regexp是一个路径解析器。
<Route path="/users/:id" component={User}/>
没有path的路由总是匹配的。
1.7. exact: bool
精确匹配
当为true,路径完全与location.pathname相匹配时才算匹配成功。
<Route exact path="/one" component={About}/>
| path | location.pathname | exact | matches? |
|---|---|---|---|
/one |
/one |
true |
yes |
/one |
/one/ |
true |
yes |
/one |
/one/two |
true |
no |
/one |
/one |
false |
yes |
/one |
/one/ |
false |
yes |
/one |
/one/two |
false |
yes |
| -- | -- | -- | -- |
/one/ |
/one |
true |
yes |
/one/ |
/one/ |
true |
yes |
/one/ |
/one/two |
true |
no |
/one/ |
/one |
false |
yes |
/one/ |
/one/ |
false |
yes |
/one/ |
/one/two |
false |
yes |
在exact或非exact模式下,/one和/one/都是等价的。而区别在于/one/、/one/ 与/one/two是否匹配。
1.8. strict: bool
严格匹配
当为true时,一条末尾有斜杠的path只匹配一个末尾有斜杠的location.pathname。当在location.pathname中有其他的URL段时,这些字段对它没有影响。
<Route strict path="/one/" component={About}/>
| path | location.pathname | matches? |
|---|---|---|
/one/ |
/one |
no |
/one/ |
/one/ |
yes |
/one/ |
/one/two |
yes |
| - | - | - |
/one |
/one |
yes |
/one |
/one/ |
yes |
/one |
/one/two |
yes |
从上可以看出,strict模式的匹配是单向的,它只是针对于path中以/结尾的路径做限制。也就是说,这个规则对不以/结尾的路径不起作用。
strict会先将location.pathname中的末尾变为/,如果以一个字符或者字符串结尾,会去掉这些字符,如:/one/two会被转为/one/。因此/one/和/one不匹配,/one/和/one/two是匹配的。
但此模式对/无用,因此path='/'与任何都是匹配的。唯一有用的是使用exact。
警告: strict可以被用来来强制执行一个没有末尾斜杠的location.pathname。为了做到这点,strict和exact都必须为ture。
<Route exact strict path="/one" component={About}/>
| path | location.pathname | matches? |
|---|---|---|
/one |
/one |
yes |
/one |
/one/ |
no |
/one |
/one/two |
no |
/one/ |
/one |
no |
/one/ |
/one/ |
yes |
/one/ |
/one/two |
no |
两种模式一起用,就可以用来使匹配必须一模一样。对字符敏感,对末尾的/也敏感。
1.9. location: object
位置
<Route>元素试图匹配它的path到当前的历史位置(通常是当前的浏览器URL)。
但是,一个具有不同pathname的location也可以通过匹配来传递。
这是有用的情况,当你需要匹配一个<Route>到一个不同于当前历史位置的位置时,如动画过渡例子所示。
如果一个<Route>元素被包装在一个<Switch>中,并且匹配了传递到<Switch>的位置(或者当前的历史位置),那么传递到<Route>的location属性,将被这个<Switch>的location所覆盖。( 鉴于此处).
1.10. sensitive: bool
大小写敏感
当为true时,路径是区分大小写的
<Route sensitive path="/one" component={About}/>
| path | location.pathname | sensitive | matches? |
|---|---|---|---|
/one |
/one |
true |
yes |
/One |
/one |
false |
no |