react-router使用教程
安裝命令
npm install -S react-router基本用法
使用時,路由器Router就是React的一個組件,Router組件本身只是個容器,真正的路由要通過Route組件定義
import React from 'react'; import ReactDOM from 'react-dom'; import {Router,Route,hashHistory} from 'react-router';import App from './App.jsx'; import About from './About.jsx';ReactDOM.render(<Router history={hashHistory}><Route path="/" component={App}/><Route path="/about" component={About}/></Router> , document.getElementById('app'))路由模式
Router組件的history屬性,用來監(jiān)聽瀏覽器地址欄的變化,并將URL解析成一個地址對象,供React Router匹配,history一個可以設置三個值
- browserHistory
- hashHistory
- createMemoryHistory
如果設為browserHistory,瀏覽器顯示的路徑是 example.com/some/path,背后調用的是瀏覽器的Histtory API.
注意:使用browserHistory時需要對服務器改造,否則用戶直接向服務器請求某個子路由,會顯示找不到網頁404錯誤,如果開發(fā)服務器是webpack-dev-server 加上--history-api-fallback參數就可以了,如下在package.json中,其他服務器的配置請參考 https://github.com/ReactTraining/react-router/blob/master/docs/guides/Histories.md#configuring-your-server
"scripts": {"dev": "webpack-dev-server --history-api-fallback --hot","build": "webpack --progress --hide-modules"},如果設為hashHistory,路由將通過URL的hash部分#切換,URL的形式類似 example.com/#/some/path
createMemoryHistory 主要用于服務器渲染,它創(chuàng)建一個內存中的history對象,不與瀏覽器URL互動。
const history = createMemoryHistory(location)嵌套路由
Route組件還可以嵌套
ReactDOM.render(<Router history={browserHistory}><Route path="/" component={Layout}><Route path="/index" component={App}/><Route path="/about" component={About}/></Route></Router> , document.getElementById('app'))上面代碼中,用戶訪問/index或/about時候會先加載Layout組件,然后在Layout組件內部加載App或Abot,為此Layout組件需要加個 {this.props.children}
import React from "react"export default React.createClass({render(){return (<div><ul><li><Link to="index">Index</Link></li><li><Link to="about">About</Link></li></ul>{this.props.children}</div>)} })上面代碼中,{this.props.children} 代表子組件 子路由也可以不寫在Router組件里面,單獨傳入Router組件的routers屬性
import React from 'react'; import ReactDOM from 'react-dom'; import {Router,Route,hashHistory,browserHistory,createMemoryHistory} from 'react-router';import Layout from './Layout.jsx'; import App from './App.jsx'; import About from './About.jsx';let routes = <Route component={Layout}><Route path="/" component={App} /><Route path="/about" component={About} /> </Route> ReactDOM.render(<Router routes={routes} history={browserHistory}></Router> , document.getElementById('app'))path屬性
Route組件的path屬性指定路由的匹配規(guī)則,這個屬性是可以省略,這樣的話,不管路徑是否匹配,總是會加載指定組件。
<Route path="home" component={Layout}><Route path="index" component={App} /><Route path="about(/:name)" component={About} /> </Route>上面的例子中當用戶訪問/home/about/map 的時候,會加載下面的組件
<Layout><About /></Layout>如果省略外層Route的path參數,寫成下面的樣子
<Route component={Layout}><Route path="index" component={App} /><Route path="about/:name" component={About} /> </Route>現(xiàn)在訪問/about/test的時候會加載下面的組件
<Layout><About /> </Layout>通配符
path屬性可以使用通配符
<Route path="/hello/:name"> 匹配 /hello/michael <Route path="/hello(/:name)> 匹配 /hello | /hello/test <Route path="/hello/*.*> 匹配 /hello/a.jpg <Route path="/hello/*> 匹配 /hello/ | /hello/test <Route path="/**/*.jpg> 匹配 /hello/a.jpg | /hello/path/to/a.jpg通配符規(guī)則如下
- :paramName 匹配URL的一個部分,知道遇到下一個/、?、#為止,這個路徑參數可以通過this.props.params.paramName取出
- () 表示URL的這個部分是可選的
- * 匹配任意字符,知道模式里面的下一個字符為止,匹配方式是非貪婪模式。
- ** 匹配任意字符,知道下一個 /、?、# 為止,匹配方式是貪婪模式。
path 屬性也可以使用相對路徑(不以/開頭),匹配時就會相對于父組件的路徑,可以參考上一節(jié)的例子。嵌套路由如果想擺脫這個規(guī)則,可以使用絕對路由。 路由匹配規(guī)則是從上到下執(zhí)行,一旦發(fā)現(xiàn)匹配,就不再匹配其余的規(guī)則了
<Route path="/hello" component="Hello"> <Route path="/hello" component="About">上面的代碼中,路徑/hello同時匹配兩個規(guī)則,第二個規(guī)則不會生效。 設置路徑參數時,需要特別小心這一點。
<Route><Route path="/:userName/:id" component="Hello"><Route path="/about/me" component="About"> </Route>上面的代碼中,用戶訪問 /about/me 的時候永遠不會觸發(fā)第二個路由規(guī)則,因為匹配到第一個規(guī)則時候就匹配上了,不會向下走了,因此 帶參數的路徑一般要寫在路由規(guī)則的底部。
此外,URL的查詢字符串 /foo?bar=baz ,可以用 this.props.location.query.bar 獲取
IndexRoute 組件
IndexRoute組件是為了解決默認情況下根路由的子組件問題的
<Router history={hashHistory}><Route path="/" component={Layout}><IndexRoute component={Index} /><Route path="app" component={App} /><Route path="about(/:name)" component={About} /></Route> </Router>上面代碼中,訪問根路徑 / 會加載Index組件到Layout組件的this.props.children
注意:IndexRoute組件沒有路徑參數path
Redirect 組件
Redirect組件用于路由的跳轉,即用戶訪問一個路由,會自動跳轉到另一個路由
<Route path="/" component={Layout}><Redirect from="/foo" to="/404" /><Route path="404" component={U404} /><Route path="app" component={App} /><Route path="about(/:name)" component={About} /> </Route>現(xiàn)在訪問/foo,就會自動跳轉到/404。
IndexRedirect 組件
IndexRedirect 組件用于訪問根路由的時候,講用戶重定向到某個子路由
<Route path="/" component={Layout}><IndexRedirect to="/404" /><Route path="404" component={U404} /><Route path="app" component={App} /><Route path="about(/:name)" component={About} /> </Route>上面代碼中,用戶訪問根路徑時,將自動重定向到子路由中
Link
Link 組件用于取代<a>元素,生成一個鏈接,允許用戶點擊后跳轉到另一個路由。它基本上就是<a>元素的React版本,可以接收Router的狀態(tài)。
<ul><li><Link to="/">Index</Link></li><li><Link to="app">App</Link></li><li><Link to="about/ggg">About</Link></li> </ul>如果希望當前的路由與其他路由有不同樣式,這時可以使用Link組件的activeStyle屬性
<li><Link to="app" activeStyle={{color:'red'}}>App</Link></li> <li><Link to="about" activeStyle={{color:'red'}}>About</Link></li>上面代碼中,當前頁面的鏈接會紅色顯示。
另一種做法是,使用activeClassName 指定當前路由的Class.
<li><Link to="app" activeClassName="active">App</Link></li> <li><Link to="about" activeClassName="active">About</Link></li>上面代碼中,當前頁面的鏈接會紅色顯示。
在Router組件之外,導航到路由頁面,可以使用瀏覽器的History API,像下面這樣寫。
import { browserHistory } from 'react-router'; browserHistory.push('/some/path');或者這樣
this.context.router.push('/some/path')IndexLink
如果鏈接到根路由/,不要使用Link組件,而要使用IndexLink組件。
這是因為對于根路由來說,activeStyle和activeClassName會失效,或者說總是生效,因為/會匹配任何子路由,而IndexLink組件會使用路徑的精確匹配
<IndexLink to="/" activeStyle={{color:'red'}}>Index</IndexLink>上面代碼中,根路由只會在精確匹配時,才會變成紅色
另一種方法是使用Link組件的 onlyActiveOnIndex屬性,也能達到同樣效果。
<Link to="/" activeStyle={{color:'red'}} onlyActiveOnIndex={true}>Index</Link>實際上,IndexLink 就是對Link組件的onlyActiveOnIndex屬性的包裝
路由的鉤子
每個路由都有Enter和Leave鉤子,用戶進入或離開該路由時觸發(fā)。
<Route path="/app" component={App} onEnter={beforeRouter} onLeave={afterRouter} />
上面的例子中,用戶進入/app的時候會觸發(fā)onEnter鉤子,用戶離開/app的時候會觸發(fā)onLeave鉤子,詳細例子請看下面
import React from 'react'; import ReactDOM from 'react-dom'; import {Router,Route,IndexRoute,hashHistory} from 'react-router';import Layout from './Layout.jsx'; import App from './App.jsx'; import Index from './Index.jsx'; import About from './About.jsx'; import NotFound from './NotFound.jsx';const beforeRouter = (nextState,replace)=>{console.log("beforeRouter",nextState,replace) }const afterRouter = (nextState,replace)=>{console.log("afterRouter",nextState,replace) }ReactDOM.render(<Router history={hashHistory}><Route path="/" component={Layout}><IndexRoute component={Index} /><Route path="app" component={App} onEnter={beforeRouter} onLeave={afterRouter} /><Route path="about(/:name)" component={About} /><Route path="*" component={NotFound} /></Route></Router> , document.getElementById('app'))本文摘自阮一峰的博客
轉載于:https://my.oschina.net/tongjh/blog/829087
總結
以上是生活随笔為你收集整理的react-router使用教程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 很好的矩阵覆盖问题
- 下一篇: POJ 3581 Sequence ——