React初識整理(四)–React Router(路由)

Grubber發表於2018-12-18

官網:https://reacttraining.com/react-router

後端路由:主要做路徑和方法的匹配,從而從後臺獲取相應的資料

前端路由:用於路徑和元件的匹配,從而實現元件的切換。 如:`<Route path=”/about” component={About}/>`

一、Router分類:

1、< BrowserRouter> 如:http://example.com/about(H5的新特性,不用寫#號,具有多樣化,使⽤了HTML5的history API來記錄你的路由歷史),如果重新整理頁面就會報404

2、 < HashRouter> 如:http://example.com/#/about 相容老的瀏覽器,使⽤URL( window.location.hash )的hash部分來記錄,可以重新整理。

二、環境配置:

  React Router庫包含三個包: react-router , react-router-dom ,和 react-routernative 。

  react-router 是路由的核⼼包,react-router-dom用於網站開發,eact-routernative 用於移動端應用開發。而且後兩者都整合了核心包 react-router ,所有在這裡我們匯入react-router-dom就好。`npm install –save react-router-dom`

三、建立路由檔案

  ①我們在src資料夾下自定義1個資料夾router,用於存放路由檔案index.js。我們優先建立了3個模組,分別為登入login、註冊register、管理主模組manage,然後將那3個模組匯出。之後在index.js裡面進行引入、配置。

import React, { Component } from `react`
import { HashRouter, Route } from "react-router-dom"
import Login from `../login`  //引入login模組
import Register from "../register"  //引入register模組
import Manage from "../manage"  //引入manage模組
//因為解構了Component,所有直接使用,否則就要用React.Component
//export default預設匯出
export default class Router extends Component {
    render() {
        return (
        //Router裡面只能有1個子元素,所有用div將多個路由包起來
            <HashRouter>
                <div>
                //Route路由,path定義路由介面,component指向模組 
                //exact={true}代表精確查詢,如不寫,則所有請求都會執行1次path="/"這個
                    <Route path="/" exact={true} component={Login} />
                    <Route path="/login"  component={Login} />
                    <Route path="/register" component={Register} />
                    <Route path="/manage" component={Manage} />
                </div>
            </HashRouter>
        )
    }
}

這裡面的Route,是React Router⾥最重要的元件。若當前路徑匹配route的路徑,它會渲染對應的UI。理想來說, < Route> 應該有⼀個叫 path 的prop,當路徑名跟當前路徑匹配才會渲染。

  ②然後在src下的主入口檔案index.js裡配置引入路由:

import React from "react"
import ReactDOM from "react-dom"

import Router from "./router"
ReactDOM.render(<Router />, document.getElementById("root"));

這樣,進入localhost:3000/dist時就引入到Router路由裡了。

四、實現頁面間的跳轉(看上去始終保持在1個頁面上)

  在這裡我們主要有兩種方式:

  ①通過< Link>標籤跳轉:React帶有< Link>標籤,相當於我們HTML裡的< a>標籤,用於做連結跳轉用的。我們先在頁面最開始匯入Link元素: `import {Link} from “react-router-dom”`, 然後就可以在模組任何地方使用了。 如:`<Link to=”/register”>新使用者註冊</Link>` 連結跳轉(點選後)到註冊的路由。這裡的to就相當於< a>標籤的href屬性,指向連結的路由地址。

  ②使用history屬性,那麼什麼是history屬性?

    - 每個router元件建立了⼀個history物件,⽤來記錄當前路徑( history.location ),上⼀步路徑也存 儲在堆疊中。當前路徑改變時,檢視會重新渲染,給你⼀種跳轉的感覺。

     – 當前路徑⼜是如何改變的呢? history物件有 history.push() 和 history.replace() 這些⽅法來實現。當你點選 < Link> 元件會觸發 history.push() ,使⽤ < Redirect> 則會調⽤ history.replace() 。

     – 其他⽅法 , 例如 history.goBack() 和 history.goForward() – ⽤來根據⻚⾯的後退和前進來跳轉history堆疊。

     – 具體使用方法:hhistory主要存在於props屬性下,我們可以通過this.props.history.push()這樣來呼叫方法。具體示例:`this.props.history.push(“/manage”);`這樣我們就可以在滿足我們條件的情況下,通過這個程式碼實現跳轉到manage的路由下了。沒錯,push進去的是路由地址,也就是我們要跳轉的路由地址。

五、Path和match

  1、Router的屬性path是⽤來標識路由匹配的URL部分,即指向對應component(元件)的路由入口。

  2、當Router的路由路徑和當前頁面的路徑成功匹配後,會生成1個物件,即match(存在於props中)。match物件包含了以下資訊:

     – match.url .返回URL匹配部分的字串。對於建立巢狀的 < Link> 很有⽤ – match.path .返回路由路徑字串

    - 就是 < Route path=””> 。將⽤來建立巢狀的 < Route>

     – match.isExact .返回布林值,如果準確(沒有任何多餘字元)匹配則返回true。

     – match.params .返回⼀個物件包含Path-to-RegExp包從URL解析的鍵值對。

六、Switch元件

  當⼀起使⽤多個 < Route> 時,所有匹配的routes都會被渲染。這個時候用Switch就很有用了,因為它只渲染匹配上的第一個元件。如:

<Switch>
    <Route exact path="/" component={login}/>
    <Route path="/register" component={Register}/>
    <Route path="/manage" component={Manage}/>
    <Route path="/:id" render = {()=>(<p>I want this  text to show up for all routes other than `/`, `/products` and `/category` </p>)}/>
</Switch>

  這裡,如果不是用Switch來包裹Route,當URL為 /register,所有匹配 /register路徑的route都會被渲染。所以,那個path為 :id 的 < Route> 會跟著 Products 元件⼀塊渲染。用Switch來包裹Route就只會渲染匹配的第一項。

七、巢狀路由

前面我們給/Login等建立了路由,那要想要/manage/students這樣的兩段路由呢?
import React, { Component } from `react`
import Students from `../students`
import Classes from "../classes"
import Teachers from "../teachers"
import { Link, Route } from "react-router-dom"

export default class Manage extends Component {
    render() {
        let { match } = this.props;
        console.log(match)
        return (
            <div>
                <ul>
                    <li><Link to={match.url + "/students"}>學生管理</Link> </li>
                    <li><Link to={match.url + "/classes"}>班級管理</Link></li>
                    <li><Link to={match.url + "/teachers"}>老師管理</Link></li>
                </ul>
                <div>
                    <Route path={match.path + "/students"} component={Students}></Route>
                    <Route path={match.path + "/classes"} component={Classes}></Route>
                    <Route path={match.path + "/teachers"} component={Teachers}></Route>
                </div>
            </div>
        )
    }
}

這裡的路由就是用manage的1段路由 match.path(構建巢狀路由)得到的,與想要配置的2段路由拼接而成,這樣的二段路由指向students這樣的巢狀元件。 然後用Link元素,用match.url獲取目前的地址(構建巢狀連結)與對應的路由拼接,從而進行匹配查詢。

 

相關文章