React中的路由系統
提起路由,首先想到的就是 ASPNET MVC 裡面的路由系統--通過事先定義一組路由規則,程序運行時就能自動根據我們輸入的URL來返回相對應的頁面。前端中的路由與之類似,前端中的路由是根據你定義的路由規則來渲染不同的頁面/組件,同時也會更新地址欄的URL。本篇文章要介紹的是React中經常使用到的路由,react-router 主要使用HTML5的history API來同步你的UI和URL。
react-router的最新版本是v4.1.1,由於4.0版本和之間的版本API變化較大,所以本篇文章的內容並不能應用到之前的版本中。
要注意 react-router 有 react-router-dom 和 react-router-native 的區別。前者是用於開發WEB應用的,而後者適用於移動APP的,本文所介紹的是react-router-dom。
react-router 中的三大組件
react-router中的組件就是react中的組件,只不過它們被添加了一些特殊的邏輯而已。
- Router Router相當於一個容器,不會被渲染出來。你的其他組件都要放在Router中才能使用到react-router的功能。根據功能的不同,Router還分為BrowserRouter,MemoryRouter等。
- Link Link被渲染稱一個a標籤,通常以聲明式的方式被定義在應用程序中。
- Route Route包含一個path,並指明了在path與URL匹配時要渲染的組件。
Router
如果說我們的應用程序是一座小城的話,那麼Route就是一座座帶有門牌號的建築物,而Link就代表了到某個建築物的路線。有了路線和目的地,那麼就缺一位老司機了,沒錯Router就是這個老司機。
先來說一說BrowserRouter。BrowserRouter主要使用在瀏覽器中,也就是WEB應用中(廢話,看名字就知道了)。它利用HTML5 的history API來同步URL和UI的變化。當我們點擊了程序中的一個鏈接之後,BrowserRouter就會找出與這個URL匹配的Route,並將他們渲染出來。 既然BrowserRouter是用來管理我們的組件的,那麼它當然要被放在最頂級的位置,而我們的應用程序的組件就作為它的一個子組件而存在。
import * as React from react;import * as ReactDOM from react-dom;import { BrowserRouter } from react-router-dom;ReactDOM.render( <BrowserRouter> <App/> </BrowserRouter>, document.body);
有時候我們的應用只是整個系統中的一個模塊,比如一個使用了ASPNET MVC中的area的後台管理模塊,應用中的URL總是以 http://localhost/admin/ 開頭。這種情況下我們總不能每次定義Link和Route的時候都帶上admin吧?react-router已經考慮到了這種情況,所以為我們提供了一個basename屬性。為BrowserRouter設置了basename之後,Link中就可以省略掉admin了,而最後渲染出來的URL又會自動帶上admin。
<BrowserRouter basename="/admin"/> ... <Link to="/home"/> // 被渲染為 <a href="/admin/home"> ...</BrowserRouter>
對於WEB應用,BrowserRouter是我們的首選。但是這裡還有一些Browser Router其他的兄弟姐妹,在其他的一些情況下你或許會用得到。
- HashRouter 這個內部使用window.location.hash,由於這裡存在一些問題,因此官方推薦使用BrowserRouter來替代。
- MemoryRouter 主要用在ReactNative這種非瀏覽器的環境中,因此直接將URL的history保存在了內存中。
- StaticRouter 主要用於服務端渲染。
Link
Link就像是一個個的路牌,為我們指明組件的位置。Link使用聲明式的方式為應用程序提供導航功能,定義的Link最終會被渲染成一個a標籤。Link使用to這個屬性來指明目標組件的路徑,可以直接使用一個字元串,也可以傳入一個對象。
// 字元串參數<Link to="/query">查詢</Link>// 對象參數<Link to={{ pathname: /query, search: ?key=name, hash: #hash}}>查詢</Link>
Link提供的功能並不多,好在我們還有NavLink可以選擇。NavLink是一個特殊版本的Link,可以使用activeClassName來設置Link被選中時被附加的class,使用activeStyle來配置被選中時應用的樣式。此外,還有一個exact屬性,此屬性要求location完全匹配才會附加class和style。這裡說的匹配是指地址欄中的URl和這個Link的to指定的location相匹配。
// 選中後被添加class selected<NavLink to={/} exact activeClassName=selected>Home</NavLink>// 選中後被附加樣式 color:red<NavLink to={/gallery} activeStyle={{color:red}}>Gallery</NavLink>
Route
Route應該是react-route中最重要的組件了,它的作用是當location與Route的path匹配時渲染Route中的Component。如果有多個Route匹配,那麼這些Route的Component都會被渲染。
與Link類似,Route也有一個exact屬性,作用也是要求location與Route的path絕對匹配。
// 當location形如 http://location/時,Home就會被渲染。// 因為 "/" 會匹配所有的URL,所以這裡設置一個exact來強制絕對匹配。<Route exact path="/" component={Home}/><Route path="/about" component={About}/>
Route的三種渲染方式
1. component: 這是最常用也最容易理解的方式,給什麼就渲染什麼。
2. render: render的類型是function,Route會渲染這個function的返回值。因此它的作用就是附加一些額外的邏輯。
<Route path="/home" render={() => { console.log(額外的邏輯); return (<div>Home</div>); }/>
3. children: 這是最特殊的渲染方式。一、它同render類似,是一個function。不同的地方在於它會被傳入一個match參數來告訴你這個Route的path和location匹配上沒有。二、第二個特殊的地方在於,即使path沒有匹配上,我們也可以將它渲染出來。秘訣就在於前面一點提到的match參數。我們可以根據這個參數來決定在匹配的時候渲染什麼,不匹配的時候又渲染什麼。
// 在匹配時,容器的calss是light,<Home />會被渲染// 在不匹配時,容器的calss是dark,<About />會被渲染<Route path=/home children={({ match }) => ( <div className={match ? light : dark}> {match ? <Home/>:<About>} </div> )}/>
所有路由中指定的組件將被傳入以下三個 props 。
- match.
- location.
- history.
這裡主要說下match.params.透過這個屬性,我們可以拿到從location中解析出來的參數。當然,如果想要接收參數,我們的Route的path也要使用特殊的寫法。
如下示例,三個Link是一個文章列表中三個鏈接,分別指向三篇id不同的文章。而Route用於渲染文章詳情頁。注意path=/p/:id ,location中的對應的段會被解析為id=1 這樣的鍵值。最終這個鍵值會作為param的鍵值存在。Route中的組件可以使用this.props.match.params.id來獲取,示例中使用了結構賦值。
<Link to=/p/1 /><Link to=/p/2 /><Link to=/p/3 />......<Route path=/p/:id render={(match)=<h3>當前文章ID:{match.params.id}</h3>)} />
Redirect
當這個組件被渲染是,location會被重寫為Redirect的to指定的新location。它的一個用途是登錄重定向,比如在用戶點了登錄並驗證通過之後,將頁面跳轉到個人主頁。
<Redirect to="/new"/>
Router中常用的組件基本上都介紹了一遍,不過也只是蜻蜓點水而已。如果想更透徹的理解路由系統,建議還是去翻看官方文檔並且試著去用一用。文中給出的示例也是非常精簡的片段,僅僅作為參考。
--------------------------------------------------------------------------------------
這篇文章以前發在了博客園,今天突然翻到就搬了過來,希望以後能堅持寫文章~~
React中的路由系統 - 行乎當行 - 博客園
推薦閱讀:
※React這樣整個全家桶真的好么?這麼碎片化會是以後前端框架的趨勢么?
※掌握這5大核心概念,你就理解了React
※React系列:React架構
※React 16.3來了:帶著全新的Context API
※asp.net mvc 項目中怎麼用react redux,vue 等前端框架?
TAG:React | reactrouter | 前端框架 |