本文同步自個人博客 Reeoo's Blog,歡迎移步前往,^_^html
本文基於
React Router v1.03
版本。react
React Router
是一個爲React
設計的強大的路由庫。能夠幫助咱們快速的實現路由功能,包括URL
和React 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
的值決定渲染哪一個組件(About
、Index
、Home
)到頁面上。這樣的作法雖然看起來很簡單,可是也增長了複雜性。服務器
想象一下,若是組件 Inbox
有一些嵌套的子組件,它們的路由規則多是這樣的:/inbox/message/12345
或者 /inbox/unread
這樣的,
上面的路由匹配規則很顯然就不能知足咱們的需求了,咱們不得不修改以前的URL解析規則,寫一堆複雜的代碼來判斷哪一種URL應該呈現哪一個組件(好比:App -> About, App -> Inbox -> Messages -> Message, App -> Inbox -> Messages -> Stats
)。react-router
React Router
首先,引入React Router
dom
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
,就能夠很輕鬆的玩轉路由。