React漫漫學習路之 React Router

React Router 是一個基於 React 之上的強大路由庫,它可讓你嚮應用中快速地添加視圖和數據流,同時保持頁面與 URL 間的同步。node

目前react-router最新版本已經到4.0+,由於新的版本是一次很是大的改動,因此這裏直接討論4.0以上版本。react

引用

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)git

主要組件

<Route>

Route組件主要的做用就是當一個location匹配路由的path時,渲染某些UI,exp:github

 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> 的三種渲染方式 :web

<Route component>  // 只有當訪問地址和路由匹配時,一個 React component 纔會被渲染,此時此組件接受 route props (match, location, history)
<Route render>    // 此方法適用於內聯渲染,不會引發意料以外的從新掛載
<Route children>   // 無論地址匹配與否都會被調用,與render的工做方式基本同樣

tips:同一個<Route>中只使用一種渲染方式,多種會被覆蓋,優先級爲component>render>children。redux

 

<Route> 的三個屬性:瀏覽器

path(string):   // 路由匹配路徑。(沒有path屬性的Route 老是會 匹配);
exact(bool):   // 爲true時,則要求路徑與location.pathname必須徹底匹配;
strict(bool):  // 爲true時,有結尾斜線的路徑只能匹配有斜線的location.pathname

 

<BrowserRouter>

<Router> 使用 HTML5 提供的 history API (pushStatereplaceState 和 popstate 事件) 來保持 UI 和 URL 的同步。服務器

屬性:react-router

basename: stringapp

做用:爲全部位置添加一個基準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>

屬性:

須要跳轉到的路徑(pathname)或地址(location)。

<Link to="/courses"/>

 

須要跳轉到的地址(location)。

<Link to={{
  pathname: '/courses',
  search: '?sort=name',
  hash: '#the-hash',
  state: { fromDashboard: true }
}}/>

 

當設置爲 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+詳情,請查看官方文檔

相關文章
相關標籤/搜索