iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 18
6
Modern Web

一步一腳印的React旅程系列 第 18

[筆記][React]React網頁好朋友Router(2)-掌握match是成功的一半

  • 分享至 

  • xImage
  •  

Hi,大家好,昨天介紹了一些關於Router的基本用法,也解決了在實作時遇到的一些問題,不過在都已經解決掉的現在就讓我們繼續學習吧!

match

Router中第一位登場的是match!在每一個Route判斷到網址的路徑相符,要渲染該組件時都會將物件match給傳進該組件中,不如...我們直接來看看他吧XD

以下的範例會直接拿昨天的結果來改,所以如果還沒有昨天的程式碼,可以到我的GutHub上clone下來,不然在範例下方我也會附上該範例的GitHub程式碼!

目前我們的專案的src/Component資料夾內有幾個組件,分別是TitleHomeAboutMain,以下讓我們修改About.jsx

import React from "react"
import { Route, Link } from "react-router-dom"

class About extends React.Component {
    render() {
        //在Route將組件渲染時,會傳入match物件,在這裡把它印出來
        console.log(this.props.match)
        return (
            <div>
                <h2>關於我們選單</h2>
                <ul>
                    {/*url是match的屬性之一,會回傳網址列的路徑*/}
                    <li><Link to={`${this.props.match.url}`}>理念介紹</Link></li>
                    <li><Link to={`${this.props.match.url}/his`}>歷史沿革</Link></li>
                </ul>
                {/*path也是match的屬性之一,會回傳透過哪個Route進入的path屬性*/}
                <Route exact path={`${this.props.match.path}`} component={Introd} />
                <Route path={`${this.props.match.path}/his`} component={His} />
            </div>
        )
    }
}

//下方簡單建立兩個組件
class Introd extends React.Component {
    render() {
        return <p>這裡是理念介紹</p>
    }
}

class His extends React.Component {
    render() {
        return <p>這裡是歷史沿革</p>
    }
}

export { About }

結果會如下:
https://ithelp.ithome.com.tw/upload/images/20181011/20106935Nd6kb5ekxx.jpg

GitHub程式目錄
GitPage頁面

match會帶著RouteurlpathisExactparams這四個屬性傳入到組件的class中,上方的範例中使用了兩個屬性:

  1. url:會返回目前網址列上的目錄。
  2. path:會返回由進入的Route中設定的path
    這兩個一定搞不太清楚有什麼差別吧!因為Route就是url符合path才會進入不是嗎?怎麼會不一樣?這個和params有關,下方會提到時會說明這部分!
  3. isExact:這個雖然沒有用到,但是這個屬性會回傳url的路徑是否要完全符合path,也就是當初有沒有在Route設定exact

params

傳入參數了!真的走到哪都會有參數可以傳XD,在Route內該怎麼傳呢!讓我們在修改一次About

import React from "react"
import { Route, Link } from "react-router-dom"

class About extends React.Component {
    render() {
        return (
            <div>
                <h2>關於我們選單</h2>
                <ul>
                    {/*這裡不變*/}
                    <li><Link to={`${this.props.match.url}/introd`}>理念介紹</Link></li>
                    <li><Link to={`${this.props.match.url}/his`}>歷史沿革</Link></li>
                </ul>
                {/*這裡在path後方的/後面加上”:type“接受參數*/}
                <Route exact path={`${this.props.match.path}/:type`} component={AboutContent} />
            </div>
        )
    }
}

//將剛剛的兩個組件合成一個AboutContent
class AboutContent extends React.Component {
    render() {
        //印出目前match的狀態
        console.log(this.props.match)
        let content
        //從match的params將參數type取出來,判斷是歷史沿革還是理念介紹
        if (this.props.match.params.type == "introd")
            content = "這裡是理念介紹"
        else
            content = "這裡是歷史沿革"

        //把判斷後的字放進<p>中回傳
        return (<p>{content}</p>)
    }
}

export { About }

雖然做法不同,但是結果還是一樣:
https://ithelp.ithome.com.tw/upload/images/20181012/20106935rycHd0KZcP.jpg

GitHub程式目錄
GitPage頁面

由上方例子可以知道兩件事情

  1. Route的參數是藉由url的位置去對應的,像上方的Link指定的to${this.props.match.url}/introd其實就是About/introd,而在Router中設定的path${this.props.match.path}/:type也就是About/:type,因為:type對應到的位置剛好是About/後的目錄introd,所以該值就會被送進到:type中。

  2. matchpathurl
    在擁有參數的情況下,match中的path會在網址的目錄上維持變數名稱,而url則是直接顯示變數值,所以如果上方About中的AboutContent組件,還需要再藉由Route輸出其他組件內容的話,在該path中用${this.props.match.path}設定就會繼續把目前擁有的變數往下傳,但如果是${this.props.match.url}就不會在擁有之前帶進來的變數了。

    另外在Linkto中,為了將變數的值傳到Route中對應到path,則是反過來使用${this.props.match.url}設定to的路徑,如果是用${this.props.match.path}的話,傳到該變數的就還是名稱,不是值。

需要注意的是如果要傳進參數,那參數的數量和目錄的數量要相等,不然就不會判斷符合,例如下方幾種例子:

  1. 傳入比參數多的目錄路徑:
    <li><Link to={`${this.props.match.url}/his/strAA`}>歷史沿革</Link></li>
    
    上方的Link在下方的Route是不會符合的:
    <Route exact path={`${this.props.match.path}/:type`} component={AboutContent} />
    
    當然,如果將上方Routeexact屬性拿掉就會符合。
  2. 設定多的參數:
    <li><Link to={`${this.props.match.url}/his`}>歷史沿革</Link></li>
    
    上方的Link在下方的Route是不會符合的:
    <Route exact path={`${this.props.match.path}/:type/:strA`} component={AboutContent} />
    
    如果是Route的參數設的比Linkto還多,那不論Route有沒有加上exact都不會符合!可不要想會有undefined這種狀況出現XD

以上是對match的一些用法,其實也只是介紹他裡面會擁有哪些資訊而已,比較不容易搞清楚的地方應該會是pathurl的部分,如果有問題的話再麻煩留言告訴我!可以一起討論!


最後謝謝各位大大的觀看,如果文章中有任何問題再麻煩留言告訴我,小弟會在盡快補充或修正文章內容的,謝謝大家/images/emoticon/emoticon41.gif

參考文章:

  1. https://reacttraining.com/react-router/web/api/match

上一篇
[筆記][React]React網頁好朋友Router(1)-基本用法篇!
下一篇
[筆記][React]React網頁好朋友Router(3)-Switch和轉址王Redirect
系列文
一步一腳印的React旅程30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
AndrewYEE
iT邦新手 3 級 ‧ 2023-02-03 16:11:15

現在DOM v6中match已經被useParams()和useLocation()取代了

我要留言

立即登入留言