入坑 React-router 4

React-router VS React-router-dom

區(qū)別

React-router 提供了一些 router 的核心功能。
React-router-dom 提供瀏覽器運行環(huán)境下的一些功能,用于 DOM 綁定,我們可以通過 DOM 的事件控制路由。

如何選用

react-router-dom 比前者多出了 <Link> <BrowserRouter> 這樣的 DOM 類組件。
因此我們只需引用 react-router-dom 這個包就行了。當然,如果搭配 redux ,你還需要使用 react-router-redux。

核心

HashRouter和BrowserRouter

HashRouterBrowserRouter 像是一個 box 所有的 route 都需要放在里面。

HashRouter

HashRouter 是通過 hash 值來對路由進行控制。使用 HashRouter,路由會默認有個#。

ReactDOM.render(
  <HashRouter>
    <div>
      <Nav />
      <Route exact path='/' component={Home}></Route>
      <Route path='/game' component={Game}></Route>
    </div>
  </HashRouter>,
  document.getElementById('root')
);

小游戲詳見: react 三子棋小游戲

BrowserRouter

BrowserRouter 使用了 HTML5 history API,保證 UI 界面和 URL 保持同步。使用 BrowserRouter ,路由不會有個#。

ReactDOM.render(
  <BrowserRouter>
    <div>
      <Nav />
      <Route exact path='/' component={Home}></Route>
      <Route path='/game' component={Game}></Route>
    </div>
  </BrowserRouter>,
  document.getElementById('root')
);
basename: string

為所有位置添加一個基準URL,當需要把頁面部署到服務器的二級目錄時,可以使用 basename 設置到此目錄。

getUserConfirmation: func

導航到此頁面前執(zhí)行的函數(shù),默認使用 window.confirm (需同 Prompt 配合使用)
此為默認行為

const getConfirmation = (message, callback) => {
  const allowTransition = window.confirm(message);
  callback(allowTransition);
}

// ========================================

ReactDOM.render(
  <BrowserRouter getUserConfirmation={getConfirmation}>
    <div>
      <Prompt message="你確定要離開當前頁面嗎?" />
      <Nav />
      <Route exact path='/' component={Home}></Route>
      <Route path='/game' component={Game}></Route>
    </div>
  </BrowserRouter>,
  document.getElementById('root')
);

傳送門:react-history

forceRefresh: bool

若為 true,導航過程中會刷新整個頁面。多在不支持 HTML5 history API 的瀏覽器中使用此功能。

keyLength: number

設置它里面路由的 location.key 的長度。默認是6。(key:點擊同一個鏈接時, location.key 都會改變。)
this.props.location

children: node

渲染唯一子元素,React組件自帶 children 屬性。
傳送門:https://reactjs.org/docs/react-api.html#react.children.only

Route

控制路徑對應顯示的組件

ReactDOM.render(
  <BrowserRouter>
    <div>
      <Nav />
      <Route exact path='/' component={Home}></Route>
      <Route path='/game' component={Game}></Route>
    </div>
  </BrowserRouter>,
  document.getElementById('root')
);
Route render methods
  • <Route component>
  • <Route render>
  • <Route children>
    同一個 <Route> 應該只使用一種渲染方法 ,大部分情況下使用 component 。
component

只有訪問地址和路由匹配時,才會渲染 React 組件。Router 將根據(jù)指定的組件,使用 React.createElement 創(chuàng)建一個新的 React 元素。(如果你向 component 提供一個內聯(lián)函數(shù),那么每次渲染都會創(chuàng)建一個新組件,這將產(chǎn)生不必要的重復裝載)

render

可以方便地進行內聯(lián)渲染和包裝,而無需進行不必要的組件重裝。傳入一個函數(shù),在位置匹配時調用,而不是使用 component 創(chuàng)建一個新的 React 元素。

警告:<Route component> 優(yōu)先于 <Route render>,因此不要在同一個 <Route> 中同時使用兩者。

children

無論 path 是否匹配都可以渲染,除此之外,它的工作原理與 render 完全一樣。路由與 URL 不匹配時 matchnull。因此,可以根據(jù)路由是否匹配,動態(tài)地調整用戶界面。

const ListItemLink = ({ to, ...rest }) => (
  <Route path={to} children={({ match }) => (
    <li className={match ? 'active' : ''}>
      <Link to={to} {...rest} />
    </li>
  )} />
)

<ul>
  <ListItemLink to="/somewhere" />
  <ListItemLink to="/somewhere-else" />
</ul>

警告:<Route component><Route render> 優(yōu)先于 <Route children>,因此不要在同一個 <Route> 中同時使用多個。

Route render methods

三種渲染方式都將提供相同的三個路由屬性

  • match
  • location
  • history
match

match 是在使用 router 之后被放入 props 中的一個屬性,在 class 創(chuàng)建的組件中我們需要通過 this.props.match 來獲取 match 之中的信息。

<BrowserRouter>
    <div>
      <Nav />
      <Route exact path='/' component={Home}></Route>
      <Route path='/game/:id' component={Game}></Route>
    </div>
  </BrowserRouter>
history

它提供了很多有用的方法可以在路由系統(tǒng)中使用。

location

它可以認為是 URL 的對象形式表示。

path: string

可以是 path-to-regexp 能夠理解的任何有效的 URL 路徑。
沒有定義 path<Route> 總是會被匹配。

exact: bool

如果為 true,則只有在 path 完全匹配 location.pathname 時才匹配。

exact path location.pathname matches?
true /home /home/list no
false /home /home/list yes
strict: bool

如果為 true,則具有尾部斜杠的 path 僅與具有尾部斜杠的 location.pathname 匹配。

path location.pathname matches?
/home/ /home no
/home/ /home/ yes
/home/ /home/list yes
sensitive: bool

如果為 true,進行匹配時將區(qū)分大小寫。

sensitive path location.pathname matches?
true /home /home yes
true /Home /home no
false /Home /home yes

Link VS NavLink

兩者都是可以控制路由跳轉的,而 NavLink 的 api 更多

Link

提供聲明式的、可訪問的導航鏈接。

to: string

一個字符串形式的鏈接地址

<Link to='/courses?sort=name' />
to: object

一個對象形式的鏈接地址,可以具有以下任何屬性:

  • pathname - 要鏈接到的路徑
  • search - 查詢參數(shù)
  • hash - URL 中的 hash
  • state - 存儲到 location 中的額外狀態(tài)數(shù)據(jù)
<Link to={{
  pathname: '/courses',
  search: '?sort=name',
  hash: '#the-hash',
  state: {
    fromDashboard: true
  }
}} />
replace: bool

當設置為 true 時,點擊鏈接后將替換歷史堆棧中的當前條目,而不是添加新條目。默認為 false。(當點擊返回時將找不到設置為 true 的頁面)

<Link to='/'>Home</Link>
<Link to='/game' replace>Game</Link>
<Link to='/list'>List</Link>

一次跳轉 '/' => '/game' => '/list' => '/'
點擊返回 '/' => '/list' => '/'

innerRef: func

允許訪問組件的底層引用。

NavLink

一個特殊版的 Link,它會在與當前 URL 匹配時為其呈現(xiàn)元素添加樣式屬性。(其實就是像為頁面導航準備的。因為導航需要有 “activated state”。)

activeClassName: string

當元素處于 activated state 時應用的類,默認為 active。與 className 屬性一起使用。

activeStyle: object

當元素處于 activated state 時應用的樣式。

exact: bool

如果為 true,則只有在位置完全匹配時才應用 activated 類/樣式。

strict: bool

如果為 true,則在確定位置是否與當前 URL 匹配時,路徑名后面的斜杠。

isActive: func

添加額外邏輯以確定鏈接是否處于激活狀態(tài)的函數(shù)。

const oddEvent = (match, location) => {
  if (!match) {
    return false;
  }
  const eventID = parseInt(match.params.eventID);
  return !isNaN(eventID) && eventID % 2 === 1;
}

<NavLink to="/events/123" isActive={oddEvent}>Event 123</NavLink>
location: object

isActive 默認比較當前歷史位置(通常是當前的瀏覽器 URL)。你也可以傳遞一個不同的 location 進行比較。

Prompt

跳轉之前的一些確認信息。

message: string

當用戶試圖離開某個位置時彈出的提示信息。

message: func

將在用戶試圖導航到下一個位置時調用。需要返回一個字符串以向用戶顯示提示,或者返回 true 允許直接跳轉。

when: bool

在應用程序中,你可以始終渲染 <Prompt> 組件,并通過設置 when={true}when={false} 以阻止或允許相應的提示,而不是根據(jù)某些條件來決定是否渲染 <Prompt> 組件。

當它的值為 true 時,會彈出提示信息。如果為 false 則不會彈出。

Redirect

<Redirect> 渲染時將導航到一個新地址,這個新地址覆蓋在訪問歷史信息里面的本該訪問的那個地址(類似服務器端重定向)。

import { Route, Redirect } from 'react-router-dom';

<Route exact path="/" render={() => (
  loggedIn ? (
    <Redirect to="/dashboard" />
  ) : (
    <PublicHomePage />
  )
)} />
to: string

要重定向到的 URL 字符串,可以是 path-to-regexp 能夠理解的任何有效的 URL 路徑。要使用的 URL 參數(shù)必須由 from 提供。

to: object

要重定向到的位置,其中 pathname 可以是 path-to-regexp 能夠理解的任何有效的 URL 路徑。

<Redirect to={{
  pathname: '/login',
  search: '?utm=your+face',
  state: {
    referrer: currentLocation
  }
}} />
push: bool

如果為 true,重定向會將新的位置推入歷史記錄,而不是替換當前條目。

from: string

將要被重定向路徑。所有匹配的 URL 參數(shù)都會提供給 to,必須包含在 to 中用到的所有參數(shù),未使用參數(shù)將被忽略。只能在 <Switch> 組件內使用 <Redirect from>

<Switch>
  <Redirect from='/old-path' to='/new-path' />
  <Route path='/new-path' component={Place} />
</Switch>
exact: bool

相當于 Route.exact。

strict: bool

相當于 Route.strict。

Switch

常常會用來包裹Route,它里面不能放其他元素,用于渲染與路徑匹配的第一個子 <Route><Redirect>

這與僅僅使用列表形式的 <Route> 有何不同?

<Switch> 只會渲染一個路由。而單純的 <Route> 列表,每一個與路徑匹配的 <Route> 都將包含在渲染范圍內。

<Route path="/about" component={About} />
<Route path="/:user" component={User} />
<Route component={NoMatch} />

如果 URL 是 /about,那么 <About>、<User><NoMatch> 將全部渲染,因為它們都與路徑匹配。這將允許我們以很多方式將 <Route> 組合成我們的應用程序,如側邊欄和面包屑、引導標簽等。

但如果我們只想選擇一個 ·<Route>· 來呈現(xiàn)。比如我們在 URL 為 ·/about· 時不想匹配 /:user,就是可以通過 <Switch> 實現(xiàn)

<Switch>
  <Route exact path="/" component={Home} />
  <Route path="/about" component={About} />
  <Route path="/:user" component={User} />
  <Route component={NoMatch} />
</Switch>
location: object

用于匹配子元素而不是當前歷史位置(通常是當前的瀏覽器 URL)的 location 對象。

children: node

所有 <Switch> 的子元素都應該是 <Route><Redirect>。只有第一個匹配當前路徑的子元素將被呈現(xiàn)。

<Route> 組件使用 path 屬性進行匹配,而 <Redirect> 組件使用它們的 from 屬性進行匹配。(沒有 path 屬性的 <Route> 或者沒有 from 屬性的 <Redirect> 將始終與當前路徑匹配。)

如果給 <Switch> 提供一個 location 屬性,它將覆蓋匹配的子元素上的 location 屬性。

<Switch>
  <Route exact path="/" component={Home} />
  <Route path="/users" component={Users} />
  <Redirect from="/accounts" to="/users" />
  <Route component={NoMatch} />
</Switch>

官方文檔:https://reacttraining.com/react-router/web/api/BrowserRouter
參考鏈接:
https://blog.csdn.net/sinat_17775997/article/details/69218382
http://react-china.org/t/react-router4/15843
https://segmentfault.com/a/1190000014294604#articleHeader0

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • React Router 4.0 (以下簡稱 RR4) 已經(jīng)正式發(fā)布,它遵循React的設計理念,即萬物皆組件。所...
    梁相輝閱讀 98,086評論 24 195
  • 萬惡的根源 距離React Router v4 正式發(fā)布也已經(jīng)過去三個月了,這周把一個React的架子做了升級,之...
    桂圓_noble閱讀 69,453評論 24 100
  • <BrowserRouter> 使用 HTML5 提供的 history API (pushState, repl...
    強子_30fd閱讀 88,032評論 0 59
  • React-Router v4 1. 設計理念1.1. 動態(tài)路由1.2. 嵌套路由1.3. 響應式路由 2. 快速...
    wlszouc閱讀 8,735評論 0 14
  • 2016.10.03《一朵花很美》 包頭 睡了一晚,體力和精神都不錯。還有半天自由時間。大家分批抵達賽汗塔拉生態(tài)園...
    Wen31閱讀 415評論 0 0

友情鏈接更多精彩內容