React Router 是一个基于 React 之上的强大路由库,它可以让你向应用中快速地添加视图和数据流,同时保持页面与 URL 之间的同步。
使用 React Router
复制 import React from ' react '
import { render } from ' react-dom '
// 首先我们需要导入一些组件...
import { Router , Route , Link } from ' react-router '
// 然后我们从应用中删除一堆代码和
// 增加一些 <Link> 元素...
const App = React . createClass ( {
render () {
return (
< div >
< h1 > App </ h1 >
{ /* 把 <a> 变成 <Link> */ }
< ul >
< li >< Link to = " /about " > About </ Link ></ li >
< li >< Link to = " /inbox " > Inbox </ Link ></ li >
</ ul >
{ /*
接着用 `this.props.children` 替换 `<Child>`
router 会帮我们找到这个 children
*/ }
{ this . props . children }
</ div >
)
}
} )
// 最后,我们用一些 <Route> 来渲染 <Router>。
// 这些就是路由提供的我们想要的东西。
React . render ((
< Router >
< Route path = " / " component = { App } >
< Route path = " about " component = { About } />
< Route path = " inbox " component = { Inbox } />
</ Route >
</ Router >
) , document . body ) 如果你不熟悉 JSX,也可以用普通对象来替代。
为了从服务器获取 message 数据,我们首先需要知道它的信息。当渲染组件时,React Router 会自动向 Route 组件中注入一些有用的信息,尤其是路径中动态部分的参数。
也可以通过 query 字符串来访问参数。比如访问 /foo?bar=baz可以通过访问 this.props.location.query.bar 从 Route 组件中获取 'baz'的值
当URL为/时,我们想渲染一个在 App中的组件。不过此时,App 的 render中的this.prop.children还是undefined。这种情况下我们可以使用 IndexRoute来设置一个默认页面。
让 UI 从 URL 中解耦出来
通过在定义 path 中使用 /messages/:id 替换 messages/:id 在多层前套路由中使用绝对路径的能力让我们对 URL 拥有绝对的掌握。我们无需在 URL 中添加更多的层级。
使用 <Redirect> 使URL重定向。
Route 可以定义 onEnter 和 onLeave 两个 hook,这些 hook 会在页面跳转确认时触发一次。这些 hook 对于一些情况非常的有用,例如权限验证或者在路由跳转前将一些数据持久化保存起来。
在路由跳转过程中
onLeave 会在所有将离开的路由中触发,从最下层的路由开始直到最外层路由结束。
如果你不想使用 JSX,也可以直接使用原生的 route 数组对象。
路由拥有三个属性来决定是否匹配一个URL
当一个给定的 URL 被调用时,整个集合中(命中的部分)都会被渲染。嵌套路由被描述成一种树形结构
匹配一个(或一部分)URL的一个字符串模式。大部分的路由路径都可以直接按照字面量理解,除了下边的特殊符号
:paramName - 匹配一段位于 /、?或#之后的URL
* - 匹配任意字符直到命中下一个字符或者整个 URL 的末尾
路由算法会根据定义的顺序自顶向下匹配路由
React Router是建立在 history 上的。简而言之,一个 history 知道如何去监听浏览器地址栏的变化,并解析这个 URL 转化为 location 对象,然后 router 使用它匹配到路由,最后正确的渲染页面。
他使用浏览器中 History API 用于处理 URL
服务器配置 arrow-up-right
服务器需要做好处理 URL 的准备。处理应用启动最初的/这样的请求是没问题的,但当用户来回跳转并在/account/123刷新时,服务器就会收到来自 account/123的请求,这时需要处理这个 URL 并响应对应的 JavaScript 代码。
Hash History 使用 URL 中的 hash # 部分去创建形如example.com/#/some/path 的路由。
对比
Hash History 不需要服务器任何配置就可以运行,但是我们不推荐在实际线上环境中使用,因为每一个 web 应用都应该渴望使用 browserHistory。
传递参数
当一个 History 通过应用程序中的 push 或 replace跳转时,他可以在新的 location中存储 location state而不显示在 URL 中,这就像是在一个 HTML 中 post 的表单数据。
createMemoryHistory
Memory History 不会在地址栏被操作或读取。同时它也非常适合测试和其他渲染环境
和另外两种 history 的一点不同是必须创建它,这种方式便于测试。
默认路由 (IndexRoute) 与 IndexLink
默认路由 (IndexRoute)
Index Links
如果你在这个 app 中使用 <Link to="/">Home</Link> , 它会一直处于激活状态,因为所有的 URL 的开头都是 / 。 这确实是个问题,因为我们仅仅希望在 Home 被渲染后,激活并链接到它。
如果需要在 Home 路由被渲染后才激活的指向 / 的链接,请使用 <IndexLink to="/">Home</IndexLink>
React Router 适用于小型网站,也可以支持大型网站。
对于大型应用来说,一个首当其冲的问题就是所需加载的 JavaScript 的大小。程序应当只加载渲染页所需的 JavaScript。
路由是个非常适于做代码分拆的地方:他的责任就是配置好每个 view
React Router 里的路径匹配以及组件加载都是异步完成,不仅允许你延迟加载组件,并且可以延迟加载路由配置。在首次加载包中你只需要有一个路径定义,路由会自动解析剩下的路径。
Route 可以定义 getChildRoutes,getIndexRoute和getComponents这几个函数。他们都是异步执行,并且只有在需要的时候才被调用。称之为“逐渐匹配”。
匹配 URL 并只加载该 URL 对应页面所需的路径配置和组件。
React Router 它提供一个 routerWillLeave 钩子,使得组件可以拦截正在发生的跳转,或在离开 route 前提示用户。
return返回提示信息,在离开 route前提示用户进行确认。
通过在 route 组件中引入 Lifecycle mixin 来安装这钩子
服务端渲染与客户端渲染有些许不同
在渲染之前获得数据(用 router 帮你完成这点)
为了迎合这一需求,需要在 <Router />API 下一层使用
使用 match 在渲染之前根据 location 匹配 route
使用 RoutingContext 同步渲染route组件
路由切换时,组件生命周期的变化情况
1.当用户打开应用 '/' 页面
2.当用户从 '/'跳转到 '/invoice/123'
componentWillReceiveProps, componentDidUpdate
App 从 router 中接收到新的 props,所以触发了两个生命周期方法
3.当用户从 /invoice/123 跳转到 /invoice/789
componentWillReceiveProps, componentDidUpdate
componentWillReceiveProps, componentDidUpdate
4.当从 /invoice/789 跳转到 /accounts/123
componentWillReceiveProps, componentDidUpdate
获取数据
我们在 Invoice 组件里实现一个简单的数据获取功能