翻译原文:react-router-tutorial
全篇讲解使用react路由插件:react-router
----------------------------------
git clone https://github.com/reactjs/react-router-tutorial
cd react-router-tutorial
cd lessons/01-setting-up
npm install
npm start
现在可以打开 http://localhost:8080
本质上,React Router是一个组件
render( , document.getElementById('app'))
上述这样写将没有任何展示,除非我们配置一个路由。打开 index.js
1. 导入 Router, Route 和 hashHistory (hashHistory 管理路由历史)
2. 用 Router 组件代替原来的 App 组件
// ...
import { Router, Route, hashHistory } from 'react-router'
render((
), document.getElementById('app'))
然后可以在本地查看: http://localhost:8080
添加多个路由,创建两个新组件:
// modules/About.js
import React from 'react'
export default React.createClass({
render() {
return About
}
})
// modules/Repos.js
import React from 'react'
export default React.createClass({
render() {
return Repos
}
})
现在我们组合他们到App中,并给出对应路由路径。
// insert into index.js
import About from './modules/About'
import Repos from './modules/Repos'
render((
{/* add the routes here */}
), document.getElementById('app'))
现在可以访问 http://localhost:8080/#/about 和 http://localhost:8080/#/repos
你会经常在 App 中使用 Link 组件。Link 相当于你使用 标签当做路由一样。
下面创建几个 Link 导航
// modules/App.js
import React from 'react'
import { Link } from 'react-router'
export default React.createClass({
render() {
return (
React Router Tutorial
)
}
})
把上述建立的两个组件About和Repos嵌套在App里面,这样就可以在App内分享所有路由路径。
我们只需做两步:
首先, 把两个组件的路由作为App路由的子节点。
// index.js
// ...
render((
{/* make them children of `App` */}
), document.getElementById('app'))
然后,在App组件下渲染路由子节点的组件。(顺便加上两个路由导航,方便查看。)
// modules/App.js
// ...
render() {
return (
React Router Tutorial
{/* 添加导航 */}
{/* 添加渲染子节点 */}
{this.props.children}
)
}
// ...
这样,点击导航,就可以看到两个组件的嵌套路由渲染在 this.props.children 那里。
react-router 会把页面构造成这样:
// 当你访问 /about
// 当你访问 /repos
与标签不同的是,Link 组件如果匹配到当前访问路径是它所导航的地址,那么你可以给它不同的样式修饰(添加热点样式)。
热点样式
热点样式修饰看起来像内联样式,添加 activeStyle 到你的 Link 组件中。
// modules/App.js
About
Repos
现在被激活的导航链接是文字是红色。
热点样式类名
你也可以用样式类名代替内联样式。
// modules/App.js
About
Repos
引入样式文件在页面中。
// index.html
并在css文件index.css里写上样式。
.active {
color: green;
}
然后刷新一下页面看效果,不然Webpack没有编译,看不到效果。
导航链接包装
如果在网站有很多导航链接,我们没有必要一个一个的去定义并写出 activeClassName 或者 activeStyle。
只需要创建一个 Link 组件的包装类就可以了。
比如 创建一个新文件路径: modules/NavLink.js
// modules/NavLink.js
import React from 'react'
import { Link } from 'react-router'
export default React.createClass({
render() {
return
}
})
然后在App中的导航,直接用 NavLink 这个包装类。
// modules/App.js
import NavLink from './NavLink'
// ...
About
Repos
这样效果非常好。
思考一下下面两个URL:
/repos/reactjs/react-router
/repos/facebook/react
他们两个可以用一个正则来匹配:
/repos/:userName/:repoName
符号 : 后面的参数,在路由组件中,可以用 this.props.params[name] 来访问。这里有两个参数:userName 和 repoName 可以获取访问。
添加带参数的路由
让我们了解一下 App 如何在 /repos/:userName/:repoName 参数路由下渲染界面。
首先,创建一个新文件 modules/Repo.js 如下:
// modules/Repo.js
import React from 'react'
export default React.createClass({
render() {
return (
{this.props.params.repoName}
)
}
})
再打开 index.js 添加新路由。
// ...
// import Repo
import Repo from './modules/Repo'
render((
{/* 添加新路由 */}
), document.getElementById('app'))
现在我们加一下路由导航在 Repos.js 里面。
// Repos.js
import { Link } from 'react-router'
// ...
export default React.createClass({
render() {
return (
Repos
{/* 添加一些路由导航 */}
- React Router
- React
)
}
})
现在点击上述两个导航路由,就能看到 路由参数 repoName 在 Repos组件中 用 this.props.params 获取展示。也说明了路由参数的应用。
如果需要在通用的组件下嵌套展示其它组件,该怎么做?
首先,嵌套 Repo 路由 在 Repos 路由下,然后在Repos 组件下渲染 子节点 this.props.children。
// index.js
// ...
// Repos.js
// ...
Repos
- React Router
- React
{/* 将会渲染 `Repo.js` 组件,如果访问 /repos/:userName/:repoName 路径 */}
{this.props.children}
也可以再加一下之前的热点导航链接进来。
// modules/Repos.js
// import it
import NavLink from './NavLink'
// ...
React Router
React
// ...
当 URL 访问根路径 / ,我们希望渲染 Home 组件。先要创建一个 Home 组件,然后讨论如何把它关联到 根路径 /。
// modules/Home.js
import React from 'react'
export default React.createClass({
render() {
return Home
}
})
有一种可选方案,就是在 App 下如果有子组件页面,我们就渲染,没有的话,渲染 Home 组件:
// modules/App.js
import Home from './Home'
// ...
{/* ... */}
{this.props.children || }
//...
这样的话,我们要给 Home 组件写个路由,就像 About 和 Repos 一样,Home 变成一个大组件一样。而且访问所有路径都会触发根路由造成很多问题。
现在用另一种方式 添加一个新路由到 index.js
// index.js
// new imports:
// add `IndexRoute` to 'react-router' imports
import { Router, Route, hashHistory, IndexRoute } from 'react-router'
// and the Home component
import Home from './modules/Home'
// ...
render((
{/* 把根路由放在这里 `/` */}
), document.getElementById('app'))
现在访问 根路径 就可以看到 Home 组件渲染。应该注意的是 IndexRoute 是没有填写路径的,也没有子节点。不会造成嵌套路由匹配问题。
我们可以这么写首页导航链接
// in App.js
// ...
Home
// ...
也可以用 IndexLink 代替 NavLink 这么写:
// App.js
import { IndexLink } from 'react-router'
// ...
Home
onlyActiveOnIndex 属性
当使用 Link 组件的时候,我们可以用 onlyActiveOnIndex 属性,如果为 true 的话,代表访问根路径的时候才会激活显示此链接类名修饰。
Home
自动导航链接有两种方式,一种通过 react-router 提供的 browserHistory ,一种通过组件的上下文环境 context 中的 路由管理对象。
代码如下:
// modules/Repos.js
import { browserHistory } from 'react-router'
// ...
handleSubmit(event) {
// ...
const path = `/repos/${userName}/${repo}`
browserHistory.push(path)
},
// ...
export default React.createClass({
// ask for `router` from context
contextTypes: {
router: React.PropTypes.object
},
// ...
handleSubmit(event) {
// ...
this.context.router.push(path)
},
// ..
})
关注微信公众号