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)
  },

  // ..
})

 

關注微信公衆號

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章