React Router V5 使用總結

1、先簡單交代幾句

對於以前沒有接觸過 React Router 的同窗來講,必定要注意:最新的React Router版本是 V5 。除此以外,還有 V2 V3 V4 版本。其中V4和V5版本的用法和理念基本上是一致的,可是和以前的V二、V3版本有較大差別。css

因此在學習以前必定要弄清楚本身使用的是哪個版本,若是是V4或者V5,V4和V5兩個版本的文檔筆記均可以參考;若是你用的是V2或者V3,那麼必定要找到對應的文檔筆記。react

在我學習React Router的時候,使用的是V5,因此這篇筆記也是對 React Router V5 的一些總結。若是你是一名React小白,我想經過這篇筆記,你能夠基本會使用React Router。若是你想更深層次地理解React Router,能夠訪問:reacttraining.com/react-route…webpack

2、React Router 的基本使用

1. 安裝

在V4和V5版本中,React Router分紅了兩個大的方向:React Web Router 和 React Native Router 。若是你是建立的React Web應用,就使用React Web Router ,這裏咱們使用的就是這個Router,因此執行如下命令進行安裝:web

npm install --save react-router-dom
複製代碼

2. 在React項目中配置路由

想要在React項目中使用路由,必不可少的有兩個組件(component): BrowserRouterRoute 。在React項目中,經過如下命令引入這兩個組件:shell

import { BrowserRouter, Route } from "react-router-dom";
複製代碼

BrowserRouter 組件是React Router的核心,Route組件是React Router的具體配置。舉個例子來講:BrowserRouter 組件就像是一個文具盒,Route組件就像是一件件文具同樣,須要放在這個盒子裏。這樣咱們在使用文具的時候,只須要打開文具盒,從裏面取出便可。npm

瞭解了這層關係,咱們就能夠在React中配置路由了,配置很是簡單,示例代碼以下:瀏覽器

// React 應用中的 App.js 文件

import React from 'react';
import { BrowserRouter, Route } from 'react-router-dom'
import Set from './views/set/Set'
import Help from './views/help/Help'

class App extends React.Component {
    render() {
        return (
            <BrowserRouter>
                <Route path="/help" component={Help} />
                <Route path="/set" component={Set} />
            </BrowserRouter>
        );
    }
}

export default App;
複製代碼

在App.js文件中配置完車以後,而後在React入口文件中(通常是index.js文件),引入App.js文件並掛載到頁面上,示例代碼以下:服務器

// React 應用中的入口文件 index.js 

import React from 'react'
import { render } from 'react-dom'
import App from './App'

render((
   <App /> ), document.getElementById('root')) 複製代碼

掛載完成以後,經過npm run start 等命令啓動本地開發服務器,就能夠經過路由訪問咱們的React項目了。實例以下:react-router

簡單介紹一下以上代碼中的路由配置規則,以這條路由配置爲例:dom

<Route path="/help" component={Help} />
複製代碼

Help 是咱們以前定義好的一個React組件,該組件的定義代碼以下:

import React, { Component } from 'react'

class Help extends Component {
    render() {
        return (
            <div className="help-box"> 幫助與反饋 - 頁面 </div>
        );
    }
}

export default Help;
複製代碼

當咱們在瀏覽器地址欄中輸入 http://localhost:3000/help 的時候,React Router 會匹配到 <Route path="/help" component={Help} /> 這一條記錄,而後就會在當前位置渲染對應的component。

注意是當前位置,說得更通俗一點:就是使用將Help組件中的代碼替換掉 <Route path="/help" component={Help} /> 代碼,進而渲染出路由對應的component。關於這一點,後面會有更詳細的解釋。

3. 在React中經過連接跳轉路由

經過上面的配置,咱們已經能夠經過輸入URL來跳轉路由,可是更多狀況下,咱們但願能夠經過點擊頁面上的連接進行路由的跳轉,好比如下的示例:

想要實現這一點,咱們只須要引入 Link 這個組件便可,具體代碼以下:

// React 應用中的 App.js 文件

import React from 'react';
import { BrowserRouter, Route, Link } from 'react-router-dom'   // 引入 Link 組件
import Set from './views/set/Set'
import Help from './views/help/Help'

class App extends React.Component {
    render() {
        return (
            <BrowserRouter>
            	{/* 注意 Link 組件必定要位於 BrowserRouter 組件中 */}
                <ul>
                    <li><Link to="/help">Help</Link></li>
                    <li><Link to="/set">Set</Link></li>
                </ul>
                
                <Route path="/help" component={Help} />
                <Route path="/set" component={Set} />
            </BrowserRouter>
        );
    }
}

export default App;
複製代碼

3、React Router 的進階使用

如今咱們已經掌握了React Router的基本使用,可是這個時候咱們掌握的知識還不足以讓咱們熟練地使用它,因此下面爲你們介紹React Router更多內容。

1. Route 的匹配規則

在對Route進行配置的時候,咱們能夠傳如下參數:path、exact、component、render、children 。這些參數都不是必須的,也就是說,咱們有不少中配置Route的方式,常見的有如下幾種:

<BrowserRouter>
    <Route component={Wallet} />
    <Route path="/" component={Index} />
    <Route exact path="/" component={Index} />
    <Route path="/help" component={Help} />
    <Route path="/render" render={ () => { return <h1>我是匹配到的路由</h1> } } />
</BrowserRouter>
複製代碼

這裏分別介紹以上五種Route的配置方式:

  • <Route component={Wallet} />

    在配置Route的時候沒有指定 path 屬性,這時只要你打開項目,不管你訪問什麼路徑,這個Route都會匹配到。

  • <Route path="/" component={Index} />

    配置Route的時候,指定 path="/" ,和上面配置的效果同樣,只要你打開項目,不管你訪問什麼路徑,這個Route都會匹配到。這種配置方式咱們成爲 "非嚴格匹配" ,你在項目中訪問的任何一個路徑,裏面都會包含path="/" 的路徑。因此不管訪問什麼路徑,這個Route都會匹配到。

  • <Route exact path="/" component={Index} />

    和上面一條的配置方式不一樣,這裏在配置Route的時候,傳入了 exact 屬性,說明這個配置方式是 "嚴格匹配" ,只有當咱們訪問項目的根路徑的時候,纔會匹配到這個Route。好比:localhost:3000/ 。

  • <Route path="/help" component={Help} />

    一條很常規的Route配置方式,當咱們訪問"/help"路徑的時候,匹配到這個Route,進而渲染出對應的component。

  • <Route path="/render" render={ () => { return <h1>我是匹配到的路由</h1> } } />

    和上一條路由配置不一樣的是,這裏沒有component屬性,而是換成了render屬性。該屬性是一個函數,當匹配到這個Route的時候,頁面將會渲染出這個函數返回的內容。

2. Switch 組件的使用

Switch組件的使用其實很是簡單,舉個例子:若是說BrowserRouter組件是一個大的文具盒的話,那麼Switch組件就是這個大文具盒中的一個小袋子,Route組件就是這個小袋子中的一支鉛筆,咱們須要鉛筆的時候,直接從這個小袋子裏面取出一支便可。注意:是最多隻能取出一支鉛筆。

也就是說,當進行路由匹配的時候,一旦匹配到了Switch組件中的一個Route,那麼就不會再繼續匹配。好比如下實例:

<BrowserRouter>
    <Switch>
        <Route component={Wallet} />
        <Route path="/" component={Index} />
        <Route path="/help" component={Help} />
        <Route path="/render" render={() => { return <h1>我是匹配到的路由</h1> }} />
    </Switch>
</BrowserRouter>
複製代碼

若是咱們訪問 "localhost:3000/help" 路徑,雖然前三個Route都匹配,可是頁面只會渲染第一個匹配到的Route,其餘的都被忽略。看到這裏你可能會問,這個組件有什麼做用呢?能夠在如下場景中發揮做用:若是當前路徑沒有匹配到任何Route的時候,路由跳轉到 404 頁面,那麼就能夠這樣寫:

<BrowserRouter>
    <Switch>
        <Route path="/set" component={Set} />
        <Route path="/help" component={Help} />
        <Route path="/render" render={() => { return <h1>我是匹配到的路由</h1> }} />
        <Route component={NotFound} />
    </Switch>
</BrowserRouter>
複製代碼

經過上面的配置,若是當前路徑有匹配到最後一個以外的Route,那麼就顯示對應內容,再也不繼續匹配;若是沒有匹配到最後一個以外的Route,就顯示最後一個Route,由於這個Route能夠匹配任何路徑。能夠把這個Route對應到 404 頁面。

3. 匹配到的 Route 如何渲染內容

前面講述了Route的配置和匹配規則,下面咱們講述一下,當路徑匹配到Route以後,會如何渲染對應的內容。

以前有提到過:是在 當前位置 渲染內容,對於一些剛入門的小白來講,可能不能馬上理解當前位置是什麼位置。因此咱們舉個例子,好比咱們在項目的App.js組件中有如下配置代碼:

class App extends React.Component {
    render() {
        return (
            <div className="content">
                <BrowserRouter>
                    <Route exact path="/" component={Index} />       {/* 位置 A */}
                    <Route path="/help" component={Help} />          {/* 位置 B */}
                    <Route path="/set" component={Set} />            {/* 位置 C */}
                </BrowserRouter>
            </div>
        );
    }
}
複製代碼

那麼當路徑爲 "help" 的時候,就會匹配到第二個Route,那麼React Router就會在 位置B 對應的這一行將 Route 組件替換成Help組件;而其餘沒有匹配到的Route,會被替換成null,至關於將這些 Route 組件直接刪去。最終的結果如如下代碼所示:

// Help 組件的定義代碼能夠在上文中找到
class App extends React.Component {
    render() {
        return (
            <div className="content"> <div className="help-box"> 幫助與反饋 - 頁面 </div> </div>
        );
    }
}
複製代碼

之因此講這麼一個知識點,是爲後面介紹如何配置嵌套路由作準備,這裏能夠先提一下:若是咱們想在 組件A中 嵌套幾個子路由,那麼就能夠將這幾個Route配置,寫到組件A中,一旦路徑匹配到了這些Route,就會在組件A中對應的位置渲染子路由對應的組件。聽不懂不要緊,後面會有詳細的解釋。

4. 對 React Router 的一點解釋

經過上面的筆記,你可能會認爲:Route組件必須位於BrowserRouter組件中,且兩個組件必須在同一個文件中。

其實否則,從代碼結構上說,Route組件確實必須位於BrowserRouter組件中,可是兩個組件不必定非要在一個文件中,只要打包編譯以後,兩個組件知足Route組件位於BrowserRouter組件中就能夠。好比如下的寫法也是徹底正確的:

// 項目的入口文件 index.js
import React from 'react'
import { render } from 'react-dom'
import App from './App'
import { BrowserRouter } from 'react-router-dom'

render((
   <BrowserRouter> <App /> </BrowserRouter>
), document.getElementById('root'))
複製代碼
// App.js 文件
import React from 'react';
import { Route, NavLink } from 'react-router-dom'
import Set from './views/set/Set'
import Help from './views/help/Help'
import Index from './views/index/Index'
import Wallet from './views/wallet/Wallet'

class App extends React.Component {
    render() {
        return (
            {/* 注意這裏已經沒有了 BrowserRouter 組件 */}
            <div className="content">
                <ul>
                    <NavLink activeClassName="selected" to="help">help</NavLink >
                    <NavLink activeClassName="selected" to="index">index</NavLink >
                    <NavLink activeClassName="selected" to="wallet">wallet</NavLink >
                    <NavLink activeClassName="selected" to="set">set</NavLink >
                </ul>

                <Route path="/help" component={Help} />
                <Route path="/index" component={Index} />
                <Route path="/wallet" component={Wallet} />
                <Route path="/set" component={Set} />
            </div>
        );
    }
}

export default App;
複製代碼

5. 如何配置嵌套路由

嵌套路由,顧名思義就是在一個主路由匹配到的頁面中再配置一些路由,咱們如今就來說述如下如何使用 React Router 配置嵌套路由,配置完成以後,咱們會看到如下效果:

在以前的基礎之上,咱們已經配置好了一級路由,便可以通關點擊 set 按鈕跳轉到匹配到的Route對應的組件中,即Set組件,具體配置能夠參考上一個代碼塊中的代碼。

下面咱們要作的就是在Set組件中,進行配置二級路由,即嵌套路由。配置很是簡單,這裏先直接給出代碼:

import React, { Component } from 'react'
import { Route, Link } from 'react-router-dom'
import SetSystem from '../SetSystem'
import SetPerson from '../SetPerson'
import SetTime from '../SetTime'
import './Set.scss'

class Set extends Component {
    componentDidMount() {
        // 當前頁面匹配到的路徑,這裏是"/set"
        // 使用這個路徑,配置Route和Link
        console.log(this.props.match.path);
    }

    render() {
        return (
            <div className="set-box">
                我的設置 - 頁面

                <div className="link-list">
                    <Link to={`${this.props.match.path}/system`}>system</Link>
                    <Link to={`${this.props.match.path}/person`}>person</Link>
                    <Link to={`${this.props.match.path}/time`}>time</Link>
                </div>

                <div className="child-router">
                    <Route path={`${this.props.match.path}/system`} component={SetSystem} />
                    <Route path={`${this.props.match.path}/person`} component={SetPerson} />
                    <Route path={`${this.props.match.path}/time`} component={SetTime} />
                </div>
            </div>
        );
    }
}

export default Set;
複製代碼

注意代碼中咱們引入了 Set.scss 樣式文件,給頁面元素添加一些很是簡單的樣式,具體樣式你能夠自定義,這裏的示例代碼以下:

.set-box {
    .link-list {
        a {
            margin: 0px 10px;
        }
    }
}
複製代碼

代碼書寫完成以後,咱們就配置好了嵌套路由,啓動項目你就能夠看到上面GIF中展現的效果。這裏對上面的配置作簡單的解釋:

首先再提一下:匹配到的Route會在 當前位置 渲染匹配到的內容(這個內容多是component組件,render函數返回的結果等)。

就是由於React Router的這個特性,咱們才能配置嵌套路由,不然,及時匹配到了Route,可是咱們不知道它的渲染位置,也不能實現此功能。

其次再說一下 this.props.match 這個屬性,經過這個屬性,咱們能夠得到當前頁面,即一級路由匹配到的組件對應的路徑,在這裏 this.props.match 的值是 "/set"。

瞭解了這一點,咱們就能夠在 this.props.match 的幫助下,設置二級路由的路徑。因此如下兩種寫法是等價的,可是第一種寫法更加靈活:

{/* 第一種寫法 */}
<Link to={`${this.props.match.path}/system`}>system</Link>
<Route path={`${this.props.match.path}/system`} component={SetSystem} />

{/* 第二種寫法 */}
<Link to="/set/system">system</Link>
<Route path="/set/system" component={SetSystem} />
複製代碼

最後再再說一下 Route組件BrowserRouter組件 的位置問題。初次接觸React Router的小白可能會問:在設置嵌套路由的時候,Route組件怎麼沒有包含在BrowserRouter組件中?

事實上,在使用webpack將代碼打包打包編譯以後,Route組件已經包含在BrowserRouter組件中了。在代碼層面咱們能夠這樣理解:Route組件包含於Set組件中,Set組件包含於App組件中,App組件包含在BrowserRouter中。因此Route組件已經包含在BrowserRouter組件中。

4、寫在最後

囉囉嗦嗦寫完了對React Router的總結,內容挺多可是都很基礎,但願能夠幫到剛剛入門的小白。

若是大神們看到錯誤之處,還但願各位能及時指正。

相關文章
相關標籤/搜索