react-router API
基本用法
安装命令:
1
   | $ npm install -S react-router
   | 
 
使用展示:
1 2
   | import { Router } from 'react-router' render(<Router />, document.getElementById('app'))
  | 
 
Router 组件本身只是一个容器,真正的路由要通过 Route 组件定义。
1 2 3 4 5 6 7 8
   | import { Router, Route, hashHistory } from 'react-router'
  render(   <Router history={hashHistory}>     <Route path="/" component={App} />   </Router>,   document.getElementById('app') )
  | 
 
代码解释:
- 用户访问根路由
/(比如http://www.example.com/),组件APP就会加载到 document.getElementById(‘app’)。 
Router组件有一个参数history,它的值hashHistory表示,路由的切换由 URL 的hash变化决定,即 URL 的#部分发生变化。举例来说,用户访问http://www.example.com/,实际会看到的是http://www.example.com/#/。 
嵌套路由
Route组件定义了 URL 路径与组件的对应关系。你可以同时使用多个 Route 组件。
1 2 3 4 5
   | <Router history={hashHistory}>   <Route path="/" component={App} />   <Route path="/repos" component={Repos} />   <Route path="/about" component={About} /> </Router>
  | 
 
上面代码中,用户访问/repos时,会先加载App组件,然后在它的内部再加载Repos组件。
App 组件要写成下面的样子。
1 2 3 4 5
   | export default React.createClass({   render() {     return <div>{this.props.children}</div>   } })
  | 
 
上面代码中,App 组件的this.props.children属性就是子组件。
子路由也可以不写在Router组件里面,单独传入Router组件的routes属性。
1 2 3 4 5 6 7 8
   | let routes = (   <Route path="/" component={App}>     <Route path="/repos" component={Repos} />     <Route path="/about" component={About} />   </Route> )
  ;<Router routes={routes} history={browserHistory} />
   | 
 
path 属性
Route组件的path属性指定路由的匹配规则。这个属性是可以省略的,这样的话,不管路径是否匹配,总是会加载指定组件。
1 2 3
   | <Route path="inbox" component={Inbox}>   <Route path="messages/:id" component={Message} /> </Route>
  | 
 
上面代码中,当用户访问/inbox/messages/:id时,会加载下面的组件。
如果省略外层Route的path参数,写成下面的样子。
1 2 3
   | <Route component={Inbox}>   <Route path="inbox/messages/:id" component={Message} /> </Route>
  | 
 
通配符
1 2 3
   | <Route path="/hello/:name">
 
 
   | 
 
1 2 3 4
   | <Route path="/hello(/:name)">
 
 
 
   | 
 
1 2 3
   | <Route path="/files/*.*">
 
 
   | 
 
1 2 3 4
   | <Route path="/files/*">
 
 
 
   | 
 
通配符规则:
:paramName匹配 URL 的一个部分,直到遇到下一个/、?、#为止。这个路径参数可以通过 this.props.params.paramName 取出。 
()表示 URL 的这个部分是可选的。 
*匹配任意字符,直到模式里面的下一个字符为止。匹配方式是非贪婪模式。 
**匹配任意字符,直到下一个/、?、#为止。匹配方式是贪婪模式。 
常用组件
IndexRoute
上面的代码会发现访问根路径会加载不到子组件。IndexRoute就是解决这个问题,显式指定Home是根路由的子组件,即指定默认情况下加载的子组件。你可以把IndexRoute想象成某个路径的 index.html。
1 2 3 4 5 6 7
   | <Router>   <Route path="/" component={App}>     <IndexRoute component={Home} />     <Route path="accounts" component={Accounts} />     <Route path="statements" component={Statements} />   </Route> </Router>
   | 
 
IndexRoute组件没有路径参数path。
Redirect
<Redirect>组件用于路由的跳转,即用户访问一个路由,会自动跳转到另一个路由。
1 2 3 4
   | <Route path="inbox" component={Inbox}>   {}   <Redirect from="messages/:id" to="/messages/:id" /> </Route>
  | 
 
IndexRedirect
IndexRedirect组件用于访问根路由的时候,将用户重定向到某个子组件。
1 2 3 4 5
   | <Route path="/" component={App}>   <IndexRedirect to="/welcome" />   <Route path="welcome" component={Welcome} />   <Route path="about" component={About} /> </Route>
  | 
 
RouterContext
Link
Link组件用于取代<a>元素,生成一个链接,允许用户点击后跳转到另一个路由。它基本上就是<a>元素的React 版本,可以接收Router的状态。
1 2 3 4 5 6 7 8
   | render() {   return <div>     <ul role="nav">       <li><Link to="/about">About</Link></li>       <li><Link to="/repos">Repos</Link></li>     </ul>   </div> }
  | 
 
如果希望当前的路由与其他路由有不同样式,这时可以使用Link组件的activeStyle属性
1 2
   | <Link to="/about" activeStyle={{color: 'red'}}>About</Link> <Link to="/repos" activeStyle={{color: 'red'}}>Repos</Link>
  | 
 
另一种做法是,使用activeClassName指定当前路由的Class。
1 2
   | <Link to="/about" activeClassName="active">About</Link> <Link to="/repos" activeClassName="active">Repos</Link>
   | 
 
IndexLink
如果链接到根路由/,不要使用Link组件,而要使用IndexLink组件。
这是因为对于根路由来说,activeStyle和activeClassName会失效,或者说总是生效,因为/会匹配任何子路由。而 IndexLink 组件会使用路径的精确匹配。
1 2 3
   | <IndexLink to="/" activeClassName="active">   Home </IndexLink>
   | 
 
另一种方法是使用Link组件的onlyActiveOnIndex属性,也能达到同样效果。
1 2 3
   | <Link to="/" activeClassName="active" onlyActiveOnIndex={true}>   Home </Link>
  | 
 
实际上,IndexLink就是对Link组件的onlyActiveOnIndex属性的包装。
history
Router组件的history属性,用来监听浏览器地址栏的变化,并将 URL 解析成一个地址对象,供 React Router 匹配。
hashHistory - 如果设为hashHistory,路由将通过 URL 的 hash 部分(#)切换,URL 的形式类似 example.com/#/some/path。 
browserHistory - 如果设为browserHistory,浏览器的路由就不再通过 Hash 完成了,而显示正常的路径 example.com/some/path,背后调用的是浏览器的 History API - 种情况需要对服务器改造。否则用户直接向服务器请求某个子路由,会显示网页找不到的 404 错误。 
createMemoryHistory - createMemoryHistory主要用于服务器渲染。它创建一个内存中的 history 对象,不与浏览器 URL 互动。
javascript const history = createMemoryHistory(location) 
useRouterHistory(createHistory) 
1 2
   | import createHashHistory from 'history/lib/createHashHistory' const history = useRouterHistory(createHashHistory)({ queryKey: false })
   | 
 
表单处理
Link组件用于正常的用户点击跳转,但是有时还需要表单跳转、点击按钮跳转等操作。这些情况怎么跟 React Router 对接呢?
1 2 3 4 5
   | <form onSubmit={this.handleSubmit}>   <input type="text" placeholder="userName" />   <input type="text" placeholder="repo" />   <button type="submit">Go</button> </form>
  | 
 
第一种方法是使用browserHistory.push
1 2 3 4 5 6 7 8 9 10
   | import { browserHistory } from 'react-router'
 
    handleSubmit(event) {     event.preventDefault()     const userName = event.target.elements[0].value     const repo = event.target.elements[1].value     const path = `/repos/${userName}/${repo}`     browserHistory.push(path)   }
  | 
 
第二种方法是使用context对象。
1 2 3 4 5 6 7 8 9 10 11
   | export default React.createClass({      contextTypes: {     router: React.PropTypes.object   },
    handleSubmit(event) {          this.context.router.push(path)   } })
  | 
 
常见配置方案
1 2 3 4 5 6 7 8 9 10 11
   | React.render(   <Router>     <Route path="/" component={App}>       <Route path="about" component={About} />       <Route path="inbox" component={Inbox}>         <Route path="messages/:id" component={Message} />       </Route>     </Route>   </Router>,   document.body )
   | 
 
| URL | 
组件 | 
| / | 
APP | 
| /about | 
App -> About | 
| /inbox | 
App -> Inbox | 
| /inbox/messages/:id | 
App -> Inbox -> Message | 
添加首页
1 2 3 4 5 6 7 8 9 10 11 12 13
   | React.render(   <Router>     <Route path="/" component={App}>       {}       <IndexRoute component={Dashboard} />       <Route path="about" component={About} />       <Route path="inbox" component={Inbox}>         <Route path="messages/:id" component={Message} />       </Route>     </Route>   </Router>,   document.body )
   | 
 
| URL | 
组件 | 
| / | 
App -> Dashboard | 
| /about | 
App -> About | 
| /inbox | 
App -> Inbox | 
| /inbox/messages/:id | 
App -> Inbox -> Message | 
让 UI 从 URL 中解耦出来
1 2 3 4 5 6 7 8 9 10 11 12 13
   | React.render(   <Router>     <Route path="/" component={App}>       <IndexRoute component={Dashboard} />       <Route path="about" component={About} />       <Route path="inbox" component={Inbox}>         {}         <Route path="/messages/:id" component={Message} />       </Route>     </Route>   </Router>,   document.body )
   | 
 
| URL | 
组件 | 
| / | 
App -> Dashboard | 
| /about | 
App -> About | 
| /inbox | 
App -> Inbox | 
| /messages/:id | 
App -> Inbox -> Message | 
兼容旧的 URL
现在任何人访问 /inbox/messages/5 都会看到一个错误页面。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
   | import { Redirect } from 'react-router'
  React.render(   <Router>     <Route path="/" component={App}>       <IndexRoute component={Dashboard} />       <Route path="about" component={About} />       <Route path="inbox" component={Inbox}>         <Route path="/messages/:id" component={Message} />
          {}         <Redirect from="messages/:id" to="/messages/:id" />       </Route>     </Route>   </Router>,   document.body )
  | 
 
替换的配置方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
   | const routeConfig = [   {     path: '/',     component: App,     indexRoute: { component: Dashboard },     childRoutes: [       { path: 'about', component: About },       {         path: 'inbox',         component: Inbox,         childRoutes: [           { path: '/messages/:id', component: Message },           {             path: 'messages/:id',             onEnter: function(nextState, replaceState) {               replaceState(null, '/messages/' + nextState.params.id)             }           }         ]       }     ]   } ]
  React.render(<Router routes={routeConfig} />, document.body)
   | 
 
转载自react router 使用教程