Hi!大家好啊!想不到又重回最初的Route
篇了吧!不過其實一開始也根本沒有說到他過XD,連他的小跟班match
都提過了,就是沒有好好解釋過Route
這個組件,所以今天就來解掉昨天賣的關子吧!
經過前幾天的洗禮,大家都知道Route
可以在url
符合path
的時候,將該Route
內指定的component
給渲染出來,並利用對對應網址目錄的位置傳入param
對吧?最簡單的做法就像下方這樣子:
<Link to="/hello/GQSM">用Component渲染組件</Link>
<Route path="/hello/:userName" component={Hello}>
class Hello extends React.Component{
render(){
return <h1>Hello!{this.props.match.params.userName}!</h1>
}
}
第一行設定連結,將網址列變成to
的值。
第二行設定進入Route
的path
,符合的話渲染Hello
組件,並用:userName
來接參數。
第三行就是Hello
組件的class
,並藉由this.props.match
中的params
來取得參數userName
的值。
結果會如下(GitHub連結會在本文章的最後一起提供!):
咦?大哥你484打文章打到昏頭了?我們現在在講Route
不是class
組件哦!
Route
中也有一個render
屬性,我們能夠用inline
(行內函式)的方式寫一個function
,讓該function
像class
一樣建立一個的組件渲染,畢竟class
的本體本來就是function
對吧?讓我們來看看以下範例吧!
<Link to="/hey/GQSM">用render渲染組件</Link>
<Route path="/hey/:userName"
render={props => <h1>Hey!{props.match.params.userName}</h1>} />
第一行的Link
一樣設定了進入點。
第二行的Route
少了渲染組件的component
,取而代之的是將一個匿名函數
傳入render
中,另外為了讀到match
,記得要將props
傳入render
的匿名函式中。
結果如下:
那render
和component
有什麼不一樣嗎?
據官方的說法,如果在兩者都傳入匿名函數
的狀況下,compnent
會使用React.createElement
(應該還記得他吧XD,忘記的話可以到([筆記][React]踏出認識React的第一步回憶一下),建立一個組件出來,如果是render
的話會直接執行匿名函數,並渲染該函數return
的組件。
簡單來說,當把匿名函數放進component
的時候,每一次都會重新移除該Route
渲染的組件,再進行React.createElement
新增,所以當我們要直接在Route
中使用inline
的話,render
會是最好的選擇,只是要注意的是之前也有提到說,只有用class
才能擁有生命週期
,所以在使用時還是要看狀況取捨!
但是千萬要記得,component
的執行權會比render
還高,所以別把兩個寫進同一個Route
中,否則他還是會以component
指定的組件為主。
這個渲染方式很有趣,children
的使用方法是給他一個能夠回傳組件的匿名函式
,而不論目前url
的路徑或path
的設定為何,children
都會觸發,但是只要url
符合path
的時候Route
還是會在建構組件的時候傳入match
,而我們在依照match
的資料去判斷需要渲染怎麼樣的組件。
官方的例子使用在渲染不同樣式的Link
,首先我們新增一個class
:
class CusLink extends React.Component{
render(){
return(
<Route /*(1)*/ path={this.props.to}
/*(2)*/ children={props=>{
console.log(props.match)
//(3)
return(
<li>
{props.match ? ">" : ""}
<Link to={this.props.to}>{this.props.name}</Link>
</li>)
}} />
)
}
}
上方的class
分成三個部分解釋一下:
path
,雖然children
不論如何都會渲染,但是只有在url
符合path
時才會產生match
,不然會是null
,為了看變化,我們有在匿名函式中設定console.log(props.match)
等等可以觀察到。children
傳入一個匿名函式,記得要將props
傳入匿名函式,因為match
會出現在props
中。{props.match ? ">" : ""}
,我們要輸出的組件就像上方的例子中的Link
:
<Link to="/hey/GQSM">用render渲染組件</Link>
那當我們在使用組件時就可以以下方設定渲染出一樣的組件:
<CusLink to="/hey/GQSM" name="用render渲染組件" />
因為to
和name
分別會傳到匿名函式中props
的to
和name
,所以這裡只是把資料放在對應的位置而已。{props.match ? ">" : ""}
,因為第一點有說path
符合match
才會有值,所以我們利用這一行來判斷,如果現在的畫面是由該Route
渲染的話,就顯示一個>
在連結名稱前面。沒問題後!就可以來使用它了!既然有了連結,就直接把上方兩個例子給結合起來吧!
<div>
<ul>
<CusLink to="/hello/GQSM" name="用component渲染組件" />
<CusLink to="/hey/GQSM" name="用render渲染組件" />
</ul>
<hr />
<Route path="/hello/:userName" component={Hello} />
<Route path="/hey/:userName" render={props => <h1>Hey!{props.match.params.userName}</h1>} />
</div>
結果會如下:
url
和Route
的path
設定為何,兩個Link
都會透過Route
渲染出來。用component渲染組件
,所以改變了url
,而這時候url
就符合了Route
設定的path
,因此會將match
帶入值傳進匿名函式中,從下方綠色框框的地方可以看到match
的值。{props.match ? ">" : ""}
不是null
的話就在Link
前加個>
,所以可以看到左邊的網址是/hello/GQSM
符合Route
的path
,因此會出現>
,當點了另一個後觸發Link
的to
改變網址後就,換另一個符合Route
符合出現>
。所有的組件都環環相扣的感覺很有趣,只要理解Router
中Link
和Route
的運作原理就會發現有一定的規律在,想發現這個規律可以多下console.log
感受Router
的執行,最後附上本次範例最後的Github連結,相信一路和我一起走了20天來的各位大家一定不難看懂:
GitHub程式目錄連結
上方例子的GitPage頁面連結
今天的例子還滿適合第二十篇的XD,算是一個門檻,因為不只說明了Route
的三種渲染方法,還複習了之前React
的組件基本用法,如果在這篇有點苦手可能要到前幾天回憶一下了XD,不過主要是因為render
和children
都是傳入匿名函式產生組件,對於之前習慣用class
的我們就覺得很陌生,要去思考把class
轉換成匿名函式會是什麼樣子!
最後還是感謝各位大大的觀看,如果文章中有任何不清楚或是有問題的地方,還麻煩大家留言告訴我,小弟會在盡快修正或調整文章內容的!謝謝大家
參考文章: