React Router 是一個基於 React 之上的強大路由庫,它可以讓你向應用中快速地添加視圖和數據流,同時保持頁面與 URL 間的同步。
目前react-router最新版本已經到4.0+,因為新的版本是一次非常大的改動,所以這里直接討論4.0以上版本。
引用
react-router // React Router 核心 react-router-dom // 用於 DOM 綁定的 React Router react-router-native // 用於 React Native 的 React Router react-router-redux // React Router 和 Redux 的集成 react-router-config // 靜態路由配置的小助手
以上資源庫按需引用,本文討論web端應用,只需要引用react-router-dom即可。(如果需要搭配redux則還需引用react-router-redux)
主要組件
<Route>
Route組件主要的作用就是當一個location匹配路由的path時,渲染某些UI,exp:
1 import { BrowserRouter as Router, Route } from 'react-router-dom' 2 3 <Router> 4 <div> 5 <Route exact path="/" component={Home}/> 6 <Route path="/news" component={NewsFeed}/> 7 </div> 8 </Router> 9 // If the location of the app is / then the UI hierarchy will be something like: 10 11 <div> 12 <Home/> 13 <!-- react-empty: 2 --> 14 </div> 15 // And if the location of the app is /news then the UI hierarchy will be: 16 17 <div> 18 <!-- react-empty: 1 --> 19 <NewsFeed/> 20 </div>
<Route> 的三種渲染方式 :
<Route component> // 只有當訪問地址和路由匹配時,一個 React component 才會被渲染,此時此組件接受 route props (match, location, history) <Route render> // 此方法適用於內聯渲染,不會引起意料之外的重新掛載 <Route children> // 不管地址匹配與否都會被調用,與render的工作方式基本一樣
tips:同一個<Route>中只使用一種渲染方式,多種會被覆蓋,優先級為component>render>children。
<Route> 的三個屬性:
path(string): // 路由匹配路徑。(沒有path屬性的Route 總是會 匹配);
exact(bool): // 為true時,則要求路徑與location.pathname必須完全匹配;
strict(bool): // 為true時,有結尾斜線的路徑只能匹配有斜線的location.pathname
<BrowserRouter>
<Router>
使用 HTML5 提供的 history API (pushState
, replaceState
和 popstate
事件) 來保持 UI 和 URL 的同步。
屬性:
basename: string
作用:為所有位置添加一個基准URL(假如你需要把頁面部署到服務器的二級目錄,你可以使用 basename
設置到此目錄)
<BrowserRouter basename="/minooo" /> <Link to="/react" /> // 最終渲染為 <a href="/minooo/react">
getUserConfirmation: func
作用:導航到此頁面前執行的函數,默認使用 window.confirm
const getConfirmation = (message, callback) => { const allowTransition = window.confirm(message) callback(allowTransition) } <BrowserRouter getUserConfirmation={getConfirmation('Are you sure?', yourCallBack)} />
forceRefresh: bool
作用:當瀏覽器不支持 HTML5 的 history API 時強制刷新頁面。
const supportsHistory = 'pushState' in window.history <BrowserRouter forceRefresh={!supportsHistory} />
keyLength: number
作用:設置它里面路由的 location.key
的長度。默認是6。(key的作用:點擊同一個鏈接時,每次該路由下的 location.key
都會改變,可以通過 key 的變化來刷新頁面。)
<BrowserRouter keyLength={12} />
children: node
作用:渲染單一子元素。
<Link>
為應用提供聲明式的、無障礙導航。
import { Link } from 'react-router-dom' <Link to="/about">關於</Link>
屬性:
to: string
需要跳轉到的路徑(pathname)或地址(location)。
<Link to="/courses"/>
to: object
需要跳轉到的地址(location)。
<Link to={{ pathname: '/courses', search: '?sort=name', hash: '#the-hash', state: { fromDashboard: true } }}/>
replace: bool
當設置為 true
時,點擊鏈接后將使用新地址替換掉訪問歷史記錄里面的原地址。
當設置為 false
時,點擊鏈接后將在原有訪問歷史記錄的基礎上添加一個新的紀錄。
默認為 false
。
<NavLink>
<NavLink>
是<Link>
的一個特定版本, 會在匹配上當前 URL 的時候會給已經渲染的元素添加樣式參數
屬性
activeClassName: string
導航選中激活時候應用的樣式名,默認樣式名為 active
<NavLink to="/about" activeClassName="selected" >MyBlog</NavLink>
activeStyle: object
如果不想使用樣式名就直接寫style
<NavLink to="/about" activeStyle={{ color: 'green', fontWeight: 'bold' }} >MyBlog</NavLink>
exact: bool
若為 true,只有當訪問地址嚴格匹配時激活樣式才會應用
strict: bool
若為 true,只有當訪問地址后綴斜杠嚴格匹配(有或無)時激活樣式才會應用
isActive: func
決定導航是否激活,或者在導航激活時候做點別的事情。不管怎樣,它不能決定對應頁面是否可以渲染。
<Switch>
只渲染出第一個與當前訪問地址匹配的 <Route>
若沒有匹配則渲染 <Redirect>
import { Switch, Route } from 'react-router' <Switch> <Route exact path="/" component={Home}/> <Route path="/about" component={About}/> <Route path="/:user" component={User}/> <Redirect to={NoMatch}/> </Switch>
<Redirect>
<Redirect>
渲染時將導航到一個新地址,這個新地址覆蓋在訪問歷史信息里面的本該訪問的那個地址。
屬性
to: string
重定向的 URL 字符串
to: object
重定向的 location 對象
push: bool
若為真,重定向操作將會把新地址加入到訪問歷史記錄里面,並且無法回退到前面的頁面。
from: string
需要匹配的將要被重定向路徑。
<Prompt>
當用戶離開當前頁面前做出一些提示。
屬性
message: string
當用戶離開當前頁面時,設置的提示信息。
<Prompt message="確定要離開?" />
message: func
當用戶離開當前頁面時,設置的回掉函數
<Prompt message={location => ( `Are you sue you want to go to ${location.pathname}?` )} />
when: bool
通過設置一定條件要決定是否啟用 Prompt
對象和方法
history
history 對象通常具有以下屬性和方法:
length: number // 瀏覽歷史堆棧中的條目數 action: string // 路由跳轉到當前頁面執行的動作,分為 PUSH, REPLACE, POP location: object // 當前訪問地址信息組成的對象,具有如下屬性: pathname: string // URL路徑 search: string // URL中的查詢字符串 hash: string // URL的 hash 片段 state: string // 例如執行 push(path, state) 操作時,location 的 state 將被提供到堆棧信息里,state 只有在 browser 和 memory history 有效。 push(path, [state]) // 在歷史堆棧信息里加入一個新條目。 replace(path, [state]) // 在歷史堆棧信息里替換掉當前的條目 go(n) // 將 history 堆棧中的指針向前移動 n。 goBack() // 等同於 go(-1) goForward // 等同於 go(1) block(prompt) // 阻止跳轉
history 對象是可變的,因此建議從 <Route>
的 prop 里來獲取 location,而不是從 history.location 直接獲取。這樣可以保證 React 在生命周期中的鈎子函數正常執行,exg:
class Comp extends React.Component { componentWillReceiveProps(nextProps) { // locationChanged const locationChanged = nextProps.location !== this.props.location // 錯誤方式,locationChanged 永遠為 false,因為history 是可變的 const locationChanged = nextProps.history.location !== this.props.history.location } }
location
location 是指你當前的位置,將要去的位置,或是之前所在的位置
{ key: 'sdfad1' pathname: '/about', search: '?name=cz' hash: '#af01a', state: { price: 998 } }
在以下情境中可以獲取 location 對象
在 Route component 中,以 this.props.location 獲取 在 Route render 中,以 ({location}) => () 方式獲取 在 Route children 中,以 ({location}) => () 方式獲取 在 withRouter 中,以 this.props.location 的方式獲取
location 對象不會發生改變,因此可以在生命周期的回調函數中使用 location 對象來查看當前頁面的訪問地址是否發生改變。這種技巧在獲取遠程數據以及使用動畫時非常有用
componentWillReceiveProps(nextProps) { if (nextProps.location !== this.props.location) { // 已經跳轉了! } }
可以在不同情境中使用 location:
<Link to={location} />
<NaviveLink to={location} />
<Redirect to={location />
history.push(location)
history.replace(location)
match
match 對象包含了 <Route path> 如何與 URL 匹配的信息,具有以下屬性:
params: object // 路徑參數,通過解析 URL 中的動態部分獲得鍵值對 isExact: bool // 為 true 時,整個 URL 都需要匹配 path: string // 用來匹配的路徑模式,用於創建嵌套的 <Route> url: string // URL 匹配的部分,用於嵌套的 <Link>
獲取 match 對象
在 Route component 中,以 this.props.match獲取 在 Route render 中,以 ({match}) => () 方式獲取 在 Route children 中,以 ({match}) => () 方式獲取 在 withRouter 中,以 this.props.match的方式獲取matchPath 的返回值
更多react-router4.0+詳情,請查看官方文檔