iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 24
0
自我挑戰組

React初心者30天的探索之路系列 第 24

[Day 24] React Router- 指路者

  • 分享至 

  • xImage
  •  

以往在同個網站切換網頁的時候,就會重新刷新頁面,然後等待資源重新載入才能看到新的畫面,但是人的耐心是有限的,每次的切換如果都需要等待的話,人的耐心就會被消磨殆盡, 使用者體驗就會不盡理想,因此SPA(single page application)單頁式應用的出現就是為了解決這個問題,切換頁面不會重新刷新,有效提升使用者體驗

React是靠react-router來實作,然後爬文一下發現,怎麼有react-router和react-router-dom?簡單介紹兩者的差異如下

  • react-router:具有switch route router等方法 ,但無法透過操作DOM來跳轉
  • react-router-dom :是以react-router為核心,提供BrowserRouter 、Route Link等等 ,可以用操作DOM的方式來改變path

所以實際上我們只要引入react-router-dom即可來實作react-router的功能

首先安裝react-router-dom

npm install react-router-dom

在index.js 引入

import { BrowserRouter, Switch } from 'react-router-dom';

BrowserRouter的用途:讓其底下所有的component都能使用router,可以利用HTML5 History來進行操作
Switch的用途:讓第一個吻合url的component被渲染,如果沒有switch,所有吻合的component都會被渲染

接著將用BrowserRouter、Switch 將app component包起來

ReactDOM.render(
  <BrowserRouter>
    <Switch>
      <App />
    </Switch>
  </BrowserRouter>,
  document.getElementById('root')
);

Route

先引入Route,並且在app.js裡的jsx設定Route

import { Route } from 'react-router-dom';

Route的用途:幫路由設定對應的路徑和元件,可以說是用來定義哪個路徑配對哪個元件

<Route path="/" exact component={List} />
<Route path="/a" component={StateExample} />
<Route path="/b" component={Functional} />

Route 有幾個屬性如下:
exact:路徑需要完全符合才會導到該頁面等,等同於path===pathname,沒加的話點擊就造成 /、/a、/b均吻合路徑
path:路徑,用來比對URL
component:路徑吻合後,顯示對應的component

假如Route沒有寫path或是path='*', 並且排在前面的Route都沒被吻合的話就會被渲染,所以就可以拿來放一個預設頁面(404 not found)

<Route path="*">
    <NoMatch404 />
</Route>

路徑的部分抽離出來放在nav.js控管

import React, { Component } from 'react';
import { Link, NavLink } from 'react-router-dom';
class Nav extends Component{
    render(){
        return(
            <nav>
                <Link to="/">index</Link>
                <Link to="/a">a page</Link>
                <Link to="/b">b page</Link>
            </nav>
        )
    }
}

export default Nav

Link

import {Link} from 'react-router-dom';

設定完Route之後,就要搭配Link來設定路徑,可以想像成是a連結的功能,只是點擊後不會重新跳轉

to 可以接受字串或是物件(location object)

字串

<link to="http://test.com" />

物件

<Link to{{
  pathname: '/product',
  search: '?sort=asc',
  hash: '#hash',
  state: { isMemeber: true }
}} />

NavLink
透過activeClassName="active" ,來設定與當前URL吻合時的項目要套用active樣式 ,可以想成是進階版的link

<NavLink activeClassName="active" to="/b">b page</NavLink>

BrowserRouter與 HashRouter的差異?

BrowserRouter 網頁路徑 http://test.com/a, 需搭配server設定(ex apache、nginx),因為實際上並沒有a這個html檔案,所以不管使用者輸入什麼路徑都要導至index.html再交由react router控制

利用HTML5 history API提供的 pushState 、popState方法來控制路徑

HashRouter 網頁路徑會有#, ex.http://test.com/#b

利用window.location.hash 、hashchange控制路徑,透過改變#後面的值來切換頁面
但我是用BrowserRouter,居然也可以正常運作?那是因為create-react-app自動建立了express server的緣故,目前看到用React製作的網頁大部分都是使用BrowserRouter模式,畢竟網址當中多了個#看起來還是不太美觀

withRouter

withRouter為一個HOC component,能將location、 history等資訊 作為props傳入component,一般而言只有包在Route裡面的component才能拿到路由的資訊,如果是麵包屑component(沒有被包在Route裡面)需要取得router的資訊就可以透過withRouter

import {withRouter} from 'react-router-dom'
function App(props){     
   console.log('props',props);  
   return (<div className='app'></div>)     
} 
export default withRouter(App);  // 透過WithRouter將router等資訊傳入

印出props,可以看到有history、location,match等資訊

Redirect

如同字面上的意思,用來重新導向,不會改變原有的網址

<Redirect to="/intro" />

參考資料
https://reactrouter.com/web/example/basic


上一篇
[Day 23] React hook(下)-useMemo&useRef
下一篇
[Day 25] React Portal 任意門
系列文
React初心者30天的探索之路30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言