--- title: React - Route 路由 與 參數 tags: React date: 2021/8/18 --- ###### tags: `React` ###### *date: 2021/8/18* # ⚛️ React - Route 路由 與 參數 [TOC] ## 傳遞 params 參數 1. 首先為路由組件,傳遞 params 參數 ```jsx // 先初始化 state state = { msgArr : [ {id:'01', title:'消息1'}, {id:'02', title:'消息2'}, {id:'03', title:'消息3'}, ] } render(){ const {msgArr} = this.state return( <div> <ul> { msgArr.map((msgObj)=>{ return ( <li key={msgObj.id}> {/* 向路由組件傳遞 params 參數,需注意反斜線是 JS 表達是要用{}包起來,多個參數用 / 分隔 */} <Link to={`/home/about/${msgObj.id}/${msgObj.title}`}>{msgObj.title}</Link>} </li> ) }) } </ul> {/* 接收 params 參數要用 : 來接收,參數名稱( key )取決於 : 後面的值 */} <Route path="/home/about/:id/:title" component={Message}/> </div> ) } ``` 2. 負責接收 params 參數的路由組件,利用`console.log`來看傳遞的參數 ```jsx render(){ console.log(this.props) return( ... ) } ``` ![params](https://i.imgur.com/vFzvGyd.png) *可以看到 match 裡面的 params 有攜帶物件參數* 3. 此時 url 後面會攜帶參數,如:`.../home/about/01/消息1` 4. 如果要使用 params 參數,就可以利用`this.props.match.params`來獲取參數 ### params 參數總結 - 路由連結,需攜帶參數,多個參數用`/`分隔 - 註冊路由,需接收參數,使用`:`來接收參數 - 利用`this.props.match.params`來獲取參數 ## 傳遞 search 參數 1. 首先為路由組件,傳遞 search 參數 ```jsx // 先初始化 state state = { msgArr : [ {id:'01', title:'消息1'}, {id:'02', title:'消息2'}, {id:'03', title:'消息3'}, ] } render(){ const {msgArr} = this.state return( <div> <ul> { msgArr.map((msgObj)=>{ return ( <li key={msgObj.id}> {/* 向路由組件傳遞 search 參數,在 ? 後面寫 key=value,多個參數用 & 連接 */} <Link to={`/home/about/?id=${msgObj.id}&title=${msgObj.title}`}>{msgObj.title}</Link>} </li> ) }) } </ul> {/* search 參數不需聲明接收 */} <Route path="/home/about/" component={Message}/> </div> ) } ``` 2. 負責接收 search 參數的路由組件,利用`console.log`來看傳遞的參數 ```jsx render(){ console.log(this.props) return( ... ) } ``` ![search](https://i.imgur.com/b9pUaBz.png) *可以看到 location 裡面的 search 有攜帶 urlencoded 編碼* 3. 在接收 search 參數的組件內使用 React 內建的 JS 庫 - QueryString ```jsx import qs from 'querystring' export default class Message extends Component { render(){ console.log(this.props) const {search} = this.props.location {/* 需把第一個問號給刪掉,可以使用 slide 來去除第一個問號 */} const result = qs.parse(search.slide(1)) console.log(result) } } ``` ![obj](https://i.imgur.com/zzehsYm.png) *藉由 querystring 庫裡的 parse 方法,把 urlencoded 轉成物件型態* 4. 此時 url 後面會攜帶參數,如:`.../home/about/?id=01&title=消息1` 5. 接著就可以利用`result`的參數,來繼續後面的操作 ### search 參數總結 - 路由連結,需攜帶參數,在`?`後面寫`key=value`,多個參數用`&`連接 - 正常註冊路由 - 利用`this.props.location.search`來獲取`unlencoded` - ==注意== 獲取到的`unlencoded`需透過 QueryString 進行解析 ## 傳遞 state 參數 ==注意== :此 state 參數,與組件裡的 state 沒有關係 1. 首先為路由組件,傳遞 state 參數 ```jsx // 先初始化 state state = { msgArr : [ {id:'01', title:'消息1'}, {id:'02', title:'消息2'}, {id:'03', title:'消息3'}, ] } render(){ const {msgArr} = this.state return( <div> <ul> { msgArr.map((msgObj)=>{ return ( <li key={msgObj.id}> {/* 向路由組件傳遞 state 參數,在 JS 表達式內傳遞物件,物件內要有 pathname, state */} <Link to={{ pathname:'/home/about/message', state: { id: msgObj.id, title: msgObj.title } }}>{msgObj.title}</Link>} </li> ) }) } </ul> {/* state 參數不需聲明接收 */} <Route path="/home/about/" component={Message}/> </div> ) } ``` 2. 負責接收 state 參數的路由組件,利用`console.log`來看傳遞的參數 ```jsx render(){ console.log(this.props) return( ... ) } ``` ![state](https://i.imgur.com/xvAYTv8.png) *可以看到 location 裡面的 state 有攜帶物件參數* 3. 此時 url 後面並不會攜帶參數,如:`.../home/about` ==注意== - 因為沒攜帶參數,所以是藉由`history`內的`location`來獲取參數 - 如果`history`清除紀錄,`location`裡的`state`會變成`undefined` - 所以要使用判斷表達式,如果是`undefined`就傳遞空物件,來避免無法預期的出錯 4. 如果要使用 state 參數,就可以利用`this.props.location.state`來獲取參數 ### state 參數總結 - 路由連結,需攜帶參數,在`to`裡面{新增物件`{{}}`|最外層是 JS 表達式},物件內需有 path 字串 與 state 物件 - 正常註冊路由 - 利用`this.props.location.state`來獲取物件參數 - ==備註== 畫面刷新也可以保留參數 ## 路由參數總結 - params 參數,最常用 - 路由連結,需攜帶參數,多個參數用`/`分隔 - 註冊路由,需接收參數,使用`:`來接收參數 - 利用`this.props.match.params`來獲取參數 - search 參數,也是有使用,但比較麻煩 - 路由連結,需攜帶參數,在`?`後面寫`key=value`,多個參數用`&`連接 - 正常註冊路由 - 利用`this.props.location.search`來獲取`unlencoded` - ==注意== 獲取到的`unlencoded`需透過 QueryString 進行解析 - state 參數,在比較需要隱私的地方會使用 - 路由連結,需攜帶參數,在`to`裡面{新增物件`{{}}`|最外層是 JS 表達式},物件內需有 path 字串 與 state 物件 - 正常註冊路由 - 利用`this.props.location.state`來獲取物件參數 - ==備註== 畫面刷新也可以保留參數 ### 參考資料 - [React 中優雅使用網址參數 QueryString](https://medium.com/itsoktomakemistakes/react-%E4%B8%AD%E5%84%AA%E9%9B%85%E4%BD%BF%E7%94%A8%E7%B6%B2%E5%9D%80%E5%8F%83%E6%95%B8-query-string-540bacd08486) - [React 全家桶](https://www.youtube.com/playlist?list=PLmOn9nNkQxJFJXLvkNsGsoCUxJLqyLGxu)