React Router基本用法

本文同步自個人博客 Reeoo's Blog,歡迎移步前往,^_^html

概覽

本文基於React Router v1.03版本。react

React Router是一個爲React設計的強大的路由庫。能夠幫助咱們快速的實現路由功能,包括URLReact components之間的同步映射關係。
在解釋React Router如何使用以前,咱們先來看看在不使用React Router的狀況下,是怎麼樣的,接下來的全部例子中都將使用ES2015語法和語言特性。瀏覽器

不使用React Router

import React from 'react'
import { render } from 'react-dom'

const About = React.createClass({/*...*/})
const Inbox = React.createClass({/*...*/})
const Home = React.createClass({/*...*/})

const App = React.createClass({
getInitialState() {
  return {
    route: window.location.hash.substr(1)
  }
},

componentDidMount() {
  window.addEventListener('hashchange', () => {
    this.setState({
      route: window.location.hash.substr(1)
    })
  })
},

render() {
  let Child
  switch (this.state.route) {
    case '/about': Child = About; break;
    case '/inbox': Child = Inbox; break;
    default:      Child = Home;
  }

  return (
    <div>
      <h1>App</h1>
      <ul>
        <li><a href="#/about">About</a></li>
        <li><a href="#/inbox">Inbox</a></li>
      </ul>
      <Child/>
    </div>
  )
}
})

render(<App />, document.body)

hash值變化的時候,App 將會根據this.state.route 的值決定渲染哪一個組件(AboutIndexHome)到頁面上。這樣的作法雖然看起來很簡單,可是也增長了複雜性。服務器

想象一下,若是組件 Inbox 有一些嵌套的子組件,它們的路由規則多是這樣的:/inbox/message/12345 或者 /inbox/unread 這樣的,
上面的路由匹配規則很顯然就不能知足咱們的需求了,咱們不得不修改以前的URL解析規則,寫一堆複雜的代碼來判斷哪一種URL應該呈現哪一個組件(好比:App -> About, App -> Inbox -> Messages -> Message, App -> Inbox -> Messages -> Stats)。react-router

使用React Router

首先,引入React Routerdom

import React from 'react'
import { render } from 'react-dom'
import { Router, Route, Link } from 'react-router'

把判斷路由邏輯的那段代碼刪除,而後加入Link標籤fetch

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>

        {/*
          把`<Child>`替換成`this.props.children`
          路由會渲染正確的組件
        */}
        {this.props.children}
      </div>
    )
  }
})

最後引入<Router><Route>,由它們幫咱們搞定路由。this

render((
  <Router>
    <Route path="/" component={App}>
      <Route path="about" component={About} />
      <Route path="inbox" component={Inbox} />
    </Route>
  </Router>
), document.body)

React Router知道哪一種URL規則下,渲染哪一個組件到頁面上,不須要咱們本身在作任何的判斷。
例如:/about這種URL規則,會被構建成<App><About /></App>
React Router內部,會把<Route>標籤層級轉換成路由配置。若是你不喜歡jsx的這種寫法,也可使用對象的形式:設計

const routes = {
  path: '/',
  component: App,
  childRoutes: [
    { path: 'about', component: About },
    { path: 'inbox', component: Inbox },
  ]
}

render(<Router routes={routes} />, document.body)

添加更多的視圖

OK,如今在inbox路由下嵌套一個messages子路由,
首先須要添加一個新的Message組件:code

const Message = React.createClass({
  render() {
    return <h3>Message</h3>
  }
})

而後在原有的inbox路由下面爲 Message 組件添加新的路由,這樣就能夠獲得嵌套的組件。

const Inbox = React.createClass({
  render() {
    return (
      <div>
        <h2>Inbox</h2>
        {/* 渲染子組件 */}
        {this.props.children}
      </div>
    )
  }
})

render((
  <Router>
    <Route path="/" component={App}>
      <Route path="about" component={About} />
      <Route path="inbox" component={Inbox}>
        {/* 在這裏加入要嵌套的視圖 */}
        {/* render the stats page when at `/inbox` */}
        <IndexRoute component={InboxStats}/>
        {/* 渲染message組件  /inbox/messages/123 */}
        <Route path="messages/:id" component={Message} />
      </Route>
    </Route>
  </Router>
), document.body)

訪問inbox/messages/12345會匹配新加的路由,App->Inbox->Message,路由層級:

<App>
  <Inbox>
    <Message params={ {id: '12345'} } />
  </Inbox>
</App>

訪問/inbox,路由層級:

<App>
    <Inbox>
      <InboxStats />
    </Inbox>
</App>

獲取參數

當咱們訪問inbox/messages/12345的時候,咱們須要獲取到相應的參數,而後從服務器獲取對應的數據。當視圖渲染的時候,路由組件會注入一些有用的屬性到組件上,特別是一些從URL動態獲取的參數信息,在咱們這個示例裏是:id

const Message = React.createClass({

  componentDidMount() {
    // from the path `/inbox/messages/:id`
    const id = this.props.params.id

    fetchMessage(id, function (err, message) {
      this.setState({ message: message })
    })
  },

  // ...

})

你也能夠經過查詢串來獲取參數,假如咱們在瀏覽器裏面訪問/foo?bar=baz這個路由,在你的組件中能夠經過this.props.location.query.bar獲取bar的值baz

總結

React Router基本用法大概就這麼多,一個應用每每是各類組件各類嵌套,搞明白了React Router,就能夠很輕鬆的玩轉路由。

相關文章
相關標籤/搜索