Hi,大家好,昨天介紹了一些關於Router
的基本用法,也解決了在實作時遇到的一些問題,不過在都已經解決掉的現在就讓我們繼續學習吧!
match
在Router
中第一位登場的是match
!在每一個Route
判斷到網址的路徑相符,要渲染該組件時都會將物件match
給傳進該組件中,不如...我們直接來看看他吧XD
以下的範例會直接拿昨天的結果來改,所以如果還沒有昨天的程式碼,可以到我的GutHub上clone下來,不然在範例下方我也會附上該範例的GitHub程式碼!
目前我們的專案的src/Component
資料夾內有幾個組件,分別是Title
、Home
、About
和Main
,以下讓我們修改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 }
結果會如下:
match
會帶著Route
的url
、path
、isExact
、params
這四個屬性傳入到組件的class
中,上方的範例中使用了兩個屬性:
url
:會返回目前網址列上的目錄。path
:會返回由進入的Route
中設定的path
。Route
就是url
符合path
才會進入不是嗎?怎麼會不一樣?這個和params
有關,下方會提到時會說明這部分!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 }
雖然做法不同,但是結果還是一樣:
由上方例子可以知道兩件事情
Route
的參數是藉由url
的位置去對應的,像上方的Link
指定的to
為${this.props.match.url}/introd
其實就是About/introd
,而在Router
中設定的path
為${this.props.match.path}/:type
也就是About/:type
,因為:type
對應到的位置剛好是About/
後的目錄introd
,所以該值就會被送進到:type
中。
match
的path
和url
:
在擁有參數的情況下,match
中的path
會在網址的目錄上維持變數名稱,而url
則是直接顯示變數值,所以如果上方About
中的AboutContent
組件,還需要再藉由Route
輸出其他組件內容的話,在該path
中用${this.props.match.path}
設定就會繼續把目前擁有的變數往下傳,但如果是${this.props.match.url}
就不會在擁有之前帶進來的變數了。
另外在Link
的to
中,為了將變數的值傳到Route
中對應到path
,則是反過來使用${this.props.match.url}
設定to
的路徑,如果是用${this.props.match.path}
的話,傳到該變數的就還是名稱,不是值。
需要注意的是如果要傳進參數,那參數的數量和目錄的數量要相等,不然就不會判斷符合,例如下方幾種例子:
<li><Link to={`${this.props.match.url}/his/strAA`}>歷史沿革</Link></li>
上方的Link
在下方的Route
是不會符合的:
<Route exact path={`${this.props.match.path}/:type`} component={AboutContent} />
當然,如果將上方Route
的exact
屬性拿掉就會符合。<li><Link to={`${this.props.match.url}/his`}>歷史沿革</Link></li>
上方的Link
在下方的Route
是不會符合的:
<Route exact path={`${this.props.match.path}/:type/:strA`} component={AboutContent} />
如果是Route
的參數設的比Link
的to
還多,那不論Route
有沒有加上exact
都不會符合!可不要想會有undefined
這種狀況出現XD以上是對match
的一些用法,其實也只是介紹他裡面會擁有哪些資訊而已,比較不容易搞清楚的地方應該會是path
和url
的部分,如果有問題的話再麻煩留言告訴我!可以一起討論!
最後謝謝各位大大的觀看,如果文章中有任何問題再麻煩留言告訴我,小弟會在盡快補充或修正文章內容的,謝謝大家
參考文章: