React Router如今已是React開發單頁應用必備技能,自升級V4版本以來,許多核心API都進行了重寫,踐行路由即組件的概念,本文是我學習React Router V4以來的一些總結。react
React-Router V4是react-router的一次重大更新,許多核心API都已改變,使用react-router4不須要對路由進行集中式配置,react-router 4的核心是一切皆組件。npm
react-router 4一共被拆分爲三個包:react-router、react-router-dom、react-router-native,react-router提供了React Router的核心路由功能,包括Router, Route, Switch等,可是咱們不會直接使用它。react-router-dom和react-router-native提供在特定運行環境下的路由組件。若是你須要開發在瀏覽器中運行的Web應用,則應該安裝react-router-dom。一樣,若是你須要開發React Native應用程序,則應該安裝react-router-native。這二者都將安裝react-router做爲依賴項。api
react-router使用react-router-dom做爲瀏覽器端的路由,提供了BrowserRouter,Route,Link等api,經過DOM的事件控制路由。在Web開發過程當中,咱們更可能是使用react-router-dom。本文的討論也僅限於react-router-dom。瀏覽器
安裝bash
npm install react-router-dom --save
複製代碼
Routerreact-router
react-router4的使用首先須要選擇Router,Router用於包裹在應用最外層。Router有兩種類型:HashRouter和BrowserRouter,其表現方式也有所不一樣,使用時須要區分。app
HashRouter與BrowserRouterdom
從表面區分HashRouter和BrowserRouter的方法就是HashRouter的url中有個#,例如localhost:3000/#,HashRouter經過hash值來對路由進行控制。若是你使用HashRouter,你的路由就會默認有這個#。學習
BrowserRouter的url中沒有#,它的url如http://localhost:3001/user/login,BrowserRouter的原理是依賴HTML5的history API實現的路由機制。網站
HashRouter和BrowserRouter都具備basename屬性,若是你的URL不是位於網站根目錄,而是放在子目錄裏,你須要設置這個屬性。以下:
<BrowserRouter basename="/calendar"/>
<Link to="/today"/> // 渲染爲 <a href="/calendar/today">
複製代碼
Route Route是Router的子元素,控制路徑對應顯示的組件。經常使用屬性有exact、path以及component。 考慮如下代碼:
<Route path="/" exact component={HomePage} />
<Route path="/users" component={UsersPage} /> 複製代碼
react-router4的路由是包含性的,多個Route能夠同時進行匹配和渲染,exact控制到路徑匹配成功時不會再繼續向下匹配,在面代碼中,咱們試圖根據路徑渲染 HomePage 或者 UsersPage。若是從Route刪除了 exact 屬性,那麼在瀏覽器中訪問 /users 時,HomePage 和 UsersPage 組件將同時被渲染。
Switch
在Router組件中的任意位置建立多個,但一般咱們會把它們放在同一個位置。使用
<Switch>
<Route exact path="/" component={DashBoard} /> <Route path="/user" component={User} /> </Switch> 複製代碼
若是去掉Switch組件,當咱們訪問/user的時候,路由會同時匹配「/」和/user,將同時渲染DashBoard和User組件。
Link vs NavLink
react-router4提供了兩種導航API,用於頁面切換,當頁面切換時,頁面不會從新加載,可是組件會被從新渲染。它們做用相同,但NavLink在匹配URL成功時,能夠提供一些額外的樣式能力。
Link
Link提供to屬性控制跳轉地址,可傳入字符串或者對象。以下:
<Link to="/courses"/>to: object
<Link to={{
pathname: '/courses',
search: '?sort=name',
hash: '#the-hash',
state: { fromDashboard: true }
}}/>
複製代碼
NavLink
NavLink能夠給當前匹配成功的連接提供一個className類名,常在Tab導航中使用。
<nav>
<NavLinkto="/app"exact activeClassName="active">Home</NavLink>
<NavLinkto="/app/users"activeClassName="active">Users</NavLink>
<NavLinkto="/app/products"activeClassName="active">Products</NavLink>
</nav>
複製代碼
路徑參數 在react router4中,match用於獲取路徑上的參數,match是使用渲染時傳遞到組件內的一個props,在react組件內部經過this.props.match獲取match的屬性, 考慮以下代碼:
<Switch>
<Route exact path="/" component={DashBoard} />
<Route path="/user/:id" component={User} />
<Route path="/user" component={User} />
</Switch>
複製代碼
當訪問http://localhost:3001/user/123時,打印this.props.match的內容。 match獲取的屬性主要有:
而後,經過this.props.match.params.id就能夠獲取路由匹配的id了。
withRouter
試想,若是組件沒有經過渲染,該如何獲取history、match、location等props呢?react router4提供了一個高階組件withRouter。使用方法以下:
import { withRouter } from 'react-router-dom';
複製代碼
使用withRouter有兩種辦法,第一種簡潔的方法是使用裝飾器,以下:
@withRouter
class AuthRoute extends React.Component {
}
複製代碼
另外一種方法直接調用withRouter包裹原來的組件返回一個新的組件:
class Auth extends React.Component {
}
const AuthRoute = withRouter(Auth)
複製代碼
經過以上兩種方法,就能在組件內部使用路由的props了。以下:
const { match,location,history} = this.props;
複製代碼
關於react router4,本文只是講解了一些經常使用的api和用法,須要學習的還有不少,這裏只是開始。
本文原發於個人博客:http://yanyuanfe.cn/2018/02/02/React%20Router%20V4%20%E5%85%A5%E9%97%A8/