前一篇有提到如何安裝 react-router-dom,這一篇我們會透過實作來運用這個套件裡面的一些元件及功能。
header 的部分因為會做到 link 連結,所以我們可以使用 react-router-dom 裡面的 Link
元件來做頁面路由跳轉功能。在使用 Link
元件前,我們必須先在 index.js 中去引用 Router 元件,不然頁面會報錯,如下:
上面這個錯誤是指我們不能在 Router
元件外面使用 Link
,必須在元件裡面使用,或是用 Router
元件包住頂層元件(App
),如下面在 src 資料夾中的 index.js 裡面引入Router
元件,再進行包覆
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './pages/App';
import * as serviceWorker from './serviceWorker';
//引入 Router
import { BrowserRouter as Router} from 'react-router-dom';
ReactDOM.render(
// 用 `Router` 元件包住`App`
<React.StrictMode>
<Router><App /></Router>
</React.StrictMode>,
document.getElementById('root')
);
Link
元件使用方式很簡單,是直接用 Link
去包住連接的元素
import React from 'react';
import logo from './logo.svg';
import styles from './App.module.scss';
import { Link } from 'react-router-dom';
import HomePage from './HomePage/HomePage'; //首頁
import WorkPage from './WorkPage/WorkPage'; //作品列表頁
import WorkDetailPage from './WorkDetailPage/WorkDetailPage'; //作品詳情頁
function App() {
return (
<div className={styles.App}>
<header className={styles.header}>
<Link to="/">
<div className={styles.siteName}>
Leo's Website
</div>
</Link>
<div className={styles.menu}>
<Link to="/"><span>Home</span></Link>
<Link to="/works"><span>Works</span></Link>
</div>
</header>
<section className={styles.content}>
Content
</section>
<footer className={styles.footer}>
<div className={styles.copyright}>Copyright © 2020 LeoLiu All rights reserved.</div>
</footer>
</div>
);
}
export default App;
接下來我們可以利用 Route
來增加路由,讓 Link
改變路徑的時候能夠順利連結到其他頁面,Route
中有幾個屬性,分別是路由對應的路徑 path
,和對應的元件 component
,另外還有一個 exact
是當路由和 component 有對應才會顯示。如下:
<Route path="/" exact component={} />
我們可以先在 App.js 中新增路由,如下:
import React from 'react';
import logo from './logo.svg';
import styles from './App.module.scss';
import { Link, Route } from 'react-router-dom';
import HomePage from './HomePage/HomePage'; //首頁
import WorkPage from './WorkPage/WorkPage'; //作品列表頁
import WorkDetailPage from './WorkDetailPage/WorkDetailPage'; //作品詳情頁
function App() {
return (
<div className={styles.App}>
<header className={styles.header}>
<Link to="/">
<div className={styles.siteName}>
Leo's Website
</div>
</Link>
<div className={styles.menu}>
<Link to="/"><span>Home</span></Link>
<Link to="/works"><span>Works</span></Link>
</div>
</header>
<section className={styles.content}>
<Route path="/" exact component={ HomePage } />
<Route path="/works" exact component={ WorkPage} />
<Route path="/works/:id" exact component={ WorkDetailPage} />
</section>
<footer className={styles.footer}>
<div className={styles.copyright}>Copyright © 2020 LeoLiu All rights reserved.</div>
</footer>
</div>
);
}
export default App;
接著再製作對應的 component
,分別是 HomePage
(首頁)、WorkPage
(作品列表頁)、WorkDetailPage
(作品詳情頁),這邊放上 HomePage
程式碼範例:
import React from 'react';
const HomePage = () => {
return <div>
HomePage
</div>
}
export default HomePage;
完成對應頁面的 component 後,我們就可以利用連結來切換頁面囉(這邊因為文章編輯器似乎無法支援顯示 Route 元件,所以程式碼全部變成了白色,但是功能上是沒問題的)。
react-router-dom 有一個元件能取得當前的路由,叫做 withRouter
,我們可以利用它包住一個元件,這樣當我們調用 withRouter
時就會返回一個全新的元件,如下
import logo from './logo.svg';
import styles from './App.module.scss';
// 調用 withRouter
import { Link, Route, withRouter } from 'react-router-dom';
import HomePage from './HomePage/HomePage';
import WorkPage from './WorkPage/WorkPage';
import WorkDetailPage from './WorkDetailPage/WorkDetailPage';
const App = (props) => {
const { location } = props;
return (
//...
);
}
// 利用 withRouter 包住 App 元件
export default withRouter(App);
withRouter
擁有 react-router 的一些屬性,我們可以透過 props
解構賦值取得一個叫做 location
的屬性,這是 react-router 本身的屬性,如果 console
它,就可以看到以下這些屬性,其中的 pathname
就是當前路由名稱
透過取得路由名稱,我們就可以執行不少事情,這邊我們利用路由名稱來給連結添加樣式,這樣當連結在對應的頁面時,就會讓連結看起來比較醒目,改善使用者體驗。
import React from 'react';
import logo from './logo.svg';
import styles from './App.module.scss';
import { Link, Route, withRouter } from 'react-router-dom';
import HomePage from './HomePage/HomePage'
import WorkPage from './WorkPage/WorkPage'
import WorkDetailPage from './WorkDetailPage/WorkDetailPage'
const App = (props) => {
const { location } = props;
return (
<div className={styles.App}>
<header className={styles.header}>
<Link to="/">
<div className={styles.siteName}>
Leo's Website
</div>
</Link>
<div className={styles.menu}>
<Link to="/"><span className={ location.pathname === '/' ? styles.active : ''}>Home</span></Link>
<Link to="/works"><span className={ location.pathname === '/works' ? styles.active : ''}>Works</span></Link>
</div>
</header>
<section className={styles.content}>
<Route path="/" exact component={ HomePage } />
<Route path="/works" exact component={ WorkPage} />
<Route path="/works/:id" exact component={ WorkDetailPage} />
</section>
<footer className={styles.footer}>
<div className={styles.copyright}>Copyright © 2020 LeoLiu All rights reserved.</div>
</footer>
</div>
);
}
export default withRouter(App);
這一篇透過實作來運用一些 react-router-dom 的元件,讓我們更方便的操作路由,下一篇會將整個網站大致完成。