react-router 官方入门教程(翻译)

翻译原文:react-router-tutorial

全篇讲解使用react路由插件:react-router

----------------------------------

 

课程1:搭建项目

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

 

课程2:创建路由渲染

本质上,React Router是一个组件

render(<Router/>, document.getElementById('app'))

上述这样写将没有任何展示,除非我们配置一个路由。打开 index.js

1. 导入 Router, Route 和 hashHistory (hashHistory 管理路由历史)

2. 用 Router 组件代替原来的 App 组件

// ...
import { Router, Route, hashHistory } from 'react-router'

render((
  <Router history={hashHistory}>
    <Route path="/" component={App}/>
  </Router>
), document.getElementById('app'))

然后可以在本地查看: http://localhost:8080

添加多个路由,创建两个新组件:

  • modules/About.js
  • modules/Repos.js
// modules/About.js
import React from 'react'

export default React.createClass({
  render() {
    return <div>About</div>
  }
})


// modules/Repos.js
import React from 'react'

export default React.createClass({
  render() {
    return <div>Repos</div>
  }
})

现在我们组合他们到App中,并给出对应路由路径。

// insert into index.js
import About from './modules/About'
import Repos from './modules/Repos'

render((
  <Router history={hashHistory}>
    <Route path="/" component={App}/>
    {/* add the routes here */}
    <Route path="/repos" component={Repos}/>
    <Route path="/about" component={About}/>
  </Router>
), document.getElementById('app'))

现在可以访问 http://localhost:8080/#/about 和 http://localhost:8080/#/repos

 

课程3:用 Link 组件导航

你会经常在 App 中使用 Link 组件。Link 相当于你使用 <a> 标签当做路由一样。

下面创建几个 Link 导航

// modules/App.js
import React from 'react'
import { Link } from 'react-router'

export default React.createClass({
  render() {
    return (
      <div>
        <h1>React Router Tutorial</h1>
        <ul role="nav">
          <li><Link to="/about">About</Link></li>
          <li><Link to="/repos">Repos</Link></li>
        </ul>
      </div>
    )
  }
})

 

课程4:嵌套路由

把上述建立的两个组件About和Repos嵌套在App里面,这样就可以在App内分享所有路由路径。

我们只需做两步:

首先, 把两个组件的路由作为App路由的子节点。

// index.js
// ...
render((
  <Router history={hashHistory}>
    <Route path="/" component={App}>
      {/* make them children of `App` */}
      <Route path="/repos" component={Repos}/>
      <Route path="/about" component={About}/>
    </Route>
  </Router>
), document.getElementById('app'))

然后,在App组件下渲染路由子节点的组件。(顺便加上两个路由导航,方便查看。)

// modules/App.js
// ...
  render() {
    return (
      <div>
        <h1>React Router Tutorial</h1>
        {/* 添加导航 */}
        <ul role="nav">
          <li><Link to="/about">About</Link></li>
          <li><Link to="/repos">Repos</Link></li>
        </ul>

        {/* 添加渲染子节点 */}
        {this.props.children}

      </div>
    )
  }
// ...

这样,点击导航,就可以看到两个组件的嵌套路由渲染在 this.props.children 那里。

react-router 会把页面构造成这样:

// 当你访问  /about
<App>
    <About />
</App>

// 当你访问  /repos
<App>
    <Repos />
</App>

 

课程5:热点导航

与<a>标签不同的是,Link 组件如果匹配到当前访问路径是它所导航的地址,那么你可以给它不同的样式修饰(添加热点样式)。

 

热点样式

热点样式修饰看起来像内联样式,添加 activeStyle  到你的 Link 组件中。

// modules/App.js
<li><Link to="/about" activeStyle={{ color: 'red' }}>About</Link></li>
<li><Link to="/repos" activeStyle={{ color: 'red' }}>Repos</Link></li>

现在被激活的导航链接是文字是红色。

 

热点样式类名

你也可以用样式类名代替内联样式。

// modules/App.js
<li><Link to="/about" activeClassName="active">About</Link></li>
<li><Link to="/repos" activeClassName="active">Repos</Link></li>

引入样式文件在页面中。

// index.html
<link rel="stylesheet" href="index.css" />

并在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 <Link {...this.props} activeClassName="active"/>
  }
})

然后在App中的导航,直接用 NavLink 这个包装类。

// modules/App.js
import NavLink from './NavLink'

// ...

<li><NavLink to="/about">About</NavLink></li>
<li><NavLink to="/repos">Repos</NavLink></li>

这样效果非常好。

 

课程6:路由参数

思考一下下面两个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 (
      <div>
        <h2>{this.props.params.repoName}</h2>
      </div>
    )
  }
})

再打开 index.js 添加新路由。

// ...
// import Repo
import Repo from './modules/Repo'

render((
  <Router history={hashHistory}>
    <Route path="/" component={App}>
      <Route path="/repos" component={Repos}/>
      {/* 添加新路由 */}
      <Route path="/repos/:userName/:repoName" component={Repo}/>
      <Route path="/about" component={About}/>
    </Route>
  </Router>
), document.getElementById('app'))

现在我们加一下路由导航在 Repos.js 里面。

// Repos.js
import { Link } from 'react-router'
// ...
export default React.createClass({
  render() {
    return (
      <div>
        <h2>Repos</h2>

        {/* 添加一些路由导航 */}
        <ul>
          <li><Link to="/repos/reactjs/react-router">React Router</Link></li>
          <li><Link to="/repos/facebook/react">React</Link></li>
        </ul>

      </div>
    )
  }
})

现在点击上述两个导航路由,就能看到 路由参数 repoName 在 Repos组件中 用 this.props.params 获取展示。也说明了路由参数的应用。

 

课程7:更多嵌套

如果需要在通用的组件下嵌套展示其它组件,该怎么做?

首先,嵌套 Repo 路由 在 Repos 路由下,然后在Repos 组件下渲染 子节点 this.props.children。

// index.js
// ...
<Route path="/repos" component={Repos}>
  <Route path="/repos/:userName/:repoName" component={Repo}/>
</Route>
// Repos.js
// ...
<div>
  <h2>Repos</h2>
  <ul>
    <li><Link to="/repos/reactjs/react-router">React Router</Link></li>
    <li><Link to="/repos/facebook/react">React</Link></li>
  </ul>
  {/* 将会渲染 `Repo.js` 组件,如果访问 /repos/:userName/:repoName 路径 */}
  {this.props.children}
</div>

也可以再加一下之前的热点导航链接进来。

// modules/Repos.js
// import it
import NavLink from './NavLink'

// ...
<li><NavLink to="/repos/reactjs/react-router">React Router</NavLink></li>
<li><NavLink to="/repos/facebook/react">React</NavLink></li>
// ...

 

课程8:首页路由

当 URL 访问根路径 / ,我们希望渲染  Home 组件。先要创建一个 Home 组件,然后讨论如何把它关联到 根路径 /。

// modules/Home.js
import React from 'react'

export default React.createClass({
  render() {
    return <div>Home</div>
  }
})

有一种可选方案,就是在 App 下如果有子组件页面,我们就渲染,没有的话,渲染 Home 组件:

// modules/App.js
import Home from './Home'

// ...
<div>
  {/* ... */}
  {this.props.children || <Home/>}
</div>
//...

这样的话,我们要给 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((
  <Router history={hashHistory}>
    <Route path="/" component={App}>

      {/* 把根路由放在这里 `/` */}
      <IndexRoute component={Home}/>

      <Route path="/repos" component={Repos}>
        <Route path="/repos/:userName/:repoName" component={Repo}/>
      </Route>
      <Route path="/about" component={About}/>
    </Route>
  </Router>
), document.getElementById('app'))

现在访问 根路径 就可以看到 Home 组件渲染。应该注意的是 IndexRoute 是没有填写路径的,也没有子节点。不会造成嵌套路由匹配问题。

 

课程9:首页链接

我们可以这么写首页导航链接

// in App.js
// ...
<li><NavLink to="/">Home</NavLink></li>
// ...

也可以用 IndexLink 代替 NavLink 这么写:

// App.js
import { IndexLink } from 'react-router'

// ...
<li><IndexLink to="/" activeClassName="active">Home</IndexLink></li>

onlyActiveOnIndex 属性

 当使用 Link 组件的时候,我们可以用 onlyActiveOnIndex 属性,如果为 true 的话,代表访问根路径的时候才会激活显示此链接类名修饰。

<li><Link to="/" activeClassName="active" onlyActiveOnIndex={true}>Home</Link></li>

 

课程10,11略

课程12:自动导航链接

自动导航链接有两种方式,一种通过 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)
  },

  // ..
})

 

关注微信公众号

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值