Hi啊大家好!這幾天我一直在想該怎麼打出一篇好文章(雖然鐵人賽都過一半了XD),但這也是鐵人賽一路走來才會思考到的事情吧?在一天一篇文章持續30天的過程中,該怎麼規劃每天的內容以及文章的長度,就會變得比平常更重要!所以該怎麼說,後半段可能變成在摸索平衡的過程,如果各位大大有任何建議再請賜指教了!謝謝大家!
今天的題外話比較長,那我們繼續學習玩轉Router
的技巧吧!
Switch
Switch
也是react-router-dom
的組件之一,我們可以用它包住多個Route
,在這種情況下Switch
會控制只有在第一個Route
符合path
時才會渲染,假設以下例子:
//目前網址為:/about
//匯入Switch組件
import { Route, Switch } from "react-router-dom"
<Switch>
<Route exact path="/" component={Home} /> //(1)
<Route path="/about" component={About} /> //(2)
//雖然也符合網址的條件,但是因為在Switch中只會渲染第一個符合條件的Route
<Route path="/:type" component={type} /> //(3)
</Switch>
Route
加上了exact
,網址要嚴格等於根目錄/
才符合條件,因此不會渲染組件。Route
設定的path
,所以會被渲染。Switch
內只會進入第一個符合的Route
,所以在(2)
之後的Route
就算網址符合path
也不會進入。那這有什麼用呢?假設當前的網址目錄我們還沒完成要渲染的頁面,又不想讓使用者看見瀏覽器出現錯誤的畫面(應該也不會,只是沒有組件被渲染而已),該怎麼辦?讓我們繼續修改鞭屍About.jsx
的內容吧XD,新朋友可以從Github這裡下載!
之前的例子中在關於我們內有「理念介紹」和「歷史沿革」,以下將再加入「品牌故事」,以及網頁建構中的組件:
import React from "react"
import { Route, Link, Switch } from "react-router-dom"
class About extends React.Component {
render() {
return (
<div>
<h2>關於我們選單</h2>
<ul>
<li><Link to={`${this.props.match.url}`}>理念介紹</Link></li>
<li><Link to={`${this.props.match.url}/his`}>歷史沿革</Link></li>
<li><Link to={`${this.props.match.url}/story`}>品牌故事</Link></li>
</ul>
<Switch>
<Route exact path={`${this.props.match.path}`} component={Introd} />
<Route path={`${this.props.match.path}/his`} component={His} />
<Route component={NoPage} />
</Switch>
</div>
)
}
}
class Introd extends React.Component {
render() {
return <p>這裡是理念介紹</p>
}
}
class His extends React.Component {
render() {
return <p>這裡是歷史沿革</p>
}
}
class NoPage extends React.Component {
render() {
return <p>頁面維護中...</p>
}
}
export { About }
上方在品牌故事的Link
中設定了to={`${this.props.match.url}/story`}
但我們沒有還沒做好story
的組件,於是先建立了一個沒設定path
的Route
,也因為沒有設定,所以不論任何情況,該Route
都會符合進入渲染組件,但我們加入了Switch
就會讓狀況完全不一樣,只要該Route
之前有任何其他符合的Route
那最後一個NoPage
就不會被渲染。
Github程式連結
GitPage頁面連結
Redirect
這個組件也是react-router-dom
裡面的東西,為什麼叫轉址王呢?其實只有我取啦!其實官方叫他重定向,哈哈哈,主要是因為這個組件能夠用form
設定符合的url
,再將該url
轉到設定的to
中,這樣會很抽象嗎?哈哈哈,讓我們來看看!下方的About.jsx
每次都是他XD,不過這次我們只需要看About
的class
:
class About extends React.Component {
render() {
return (
<div>
<h2>關於我們選單</h2>
<ul>
<li><Link to={`${this.props.match.url}`}>理念介紹</Link></li>
<li><Link to={`${this.props.match.url}/his`}>歷史沿革</Link></li>
<li><Link to={`${this.props.match.url}/story`}>品牌故事</Link></li>
</ul>
<Switch>
<Route exact path={`${this.props.match.path}`} component={Introd} />
{/*(1)*/}
<Route path={`${this.props.match.path}/his`} component={His} />
<Redirect from={`${this.props.match.path}/story`} to={`${this.props.match.url}/his`} />
</Switch>
</div>
)
}
}
在程式碼中註解(1)
的地方多加了Redirect
在Switch
中,他裡面有個from
,意思是當目前的Link
連結到${this.props.match.path}/story
這個路徑的時候,Redirect
會將網址重新轉到${this.props.match.url}/his
上,我們來看看沒什麼用的示意圖,該Link
的連結還是到/story
,但跳過去後會進入Redirect
中被轉址到/his
:
基本用法如上,但是在Redirect
的to
屬性中也能夠傳入物件,物件裡面有什麼呢?讓我們來看看:
<Redirect from={`${this.props.match.path}/story`}
to={{pathname:`${this.props.match.url}/his`
,search: "?hey=UCCU"
,state:{name:'Referrer'}}} />
pathname
:這個路徑就是上方的有效路徑,也就是要重新定向的網址。search
:加在重定向的url
後當作QueryString
。state
:這個就厲害了,他能夠在傳到該路徑,而該路徑又進入某Route
時,在class
中使用this.props.location.state
取得state
的物件。為了確認我們在His
組件的render()
中加入以下行:
class His extends React.Component {
render() {
console.log(this.props.location.state)
return <p>這裡是歷史沿革</p>
}
}
接著來看看跳轉後會發生什麼事吧!
亮點有兩個地方,第一個是點擊品牌介紹後,重新定向的網址後會出現search
的值,而在跑進組件時,也能使用this.props.location.state
將state
給印出,以下附上上方例子的程式碼和執行頁面。
Umm...這樣執行起來Redirect
感覺比Route
強多了耶?不過其實不會啦!因為在Route
中也可以使用params
將參數傳到class
中啊!所以其實不會差多少,只是Redirect
是用state
當作參數,我想只是要和一般的Route
做出差別,在某些情況下能讓組件判斷到底是誰在呼叫他,並做出渲染不同的結果。
不過其實Route
還有一個未提到的屬性render
,他能做到的事情更加靈活,這裡先賣個關子,讓我們明天繼續看下去!
今天的文章到這裡結束!感謝各位大大的觀看,如果文章中有任何問題或是講解不清楚的地方,還麻煩留言告訴我,小弟會再進快修正或補充文章內容的!謝謝大家
參考文章: