2021鐵人賽
React
上一篇將選單列做出來,並且完成點擊上方按鈕會跳轉至對應頁面的功能,不過總覺得好像少了些什麼?原來是點擊按鈕之後,按鈕的樣式沒有跟著改變,會讓使用者不知道目前到底是在哪一個頁面,而所謂跟著點擊動作改變按鈕樣式的功能就稱為active。
說起來這個功能是非常簡單的,不過也是弄了蠻久,因為架構上的不熟悉以及使用react-bootstrap套件,要動態調整按鈕的active樣式變得有點困難,研究了技術文件許久才知道怎麼寫,下面就把這個過程記錄下來。
看了一下react-bootstrap官方文件,發現Nav這個component有內建activeKey功能:
Name | Type | Description |
---|---|---|
activeKey | string / number | Marks the NavItem with a matching eventKey (or href if present) as active. |
也就是說,可以使用eventKey或是href去替NavItem加上active class。使用方式如下:
目前activeKey指到/home這個路徑,那home這個NavItem就會多一個active class,所以只要可以隨著所在的路徑動態改變activeKey,就可以更動active class的位置。
<Nav
activeKey="/home"
>
<Nav.Item>
<Nav.Link href="/home">Active</Nav.Link>
</Nav.Item>
<Nav.Item>
<Nav.Link eventKey="link-1">Link</Nav.Link>
</Nav.Item>
<Nav.Item>
<Nav.Link eventKey="link-2">Link</Nav.Link>
</Nav.Item>
<Nav.Item>
<Nav.Link eventKey="disabled" disabled>
Disabled
</Nav.Link>
</Nav.Item>
</Nav>
那要怎麼動態改變activeKey呢?只要透過props將路徑傳遞給Navbar這個元件即可。因為這次傳遞路徑的架構稍微複雜了一些,所以透過props傳遞好幾層才到Navbar。
過程由上而下大概是這樣:
import React from 'react';
import './App.css';
import RouterLayer from "./routerLayer";
function App() {
return (
<div className="App">
<RouterLayer />
</div>
);
}
export default App;
import React from "react";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import routes from "../App-route";
import Layout from "../layout";
const RouterLayer = () => {
return (
<Router>
<Switch>
{routes &&
routes
.filter((r) => r.public)
.map((route) => (
<Route exact key={route.key} path={route.path}>
<Layout {...route} />
</Route>
))}
</Switch>
</Router>
);
};
export default RouterLayer;
import React from "react";
import Header from "./header";
import Body from "./body";
const Layout = (props) => {
return (
<React.Fragment>
<Header {...props} />
<Body {...props} />
</React.Fragment>
);
};
export default Layout;
import React from "react";
import Navbar from "../../components/Navbar/Navbar";
const Header = (props) => {
return <Navbar {...props} />
}
export default Header;
import React from 'react';
import styles from './Navbar.module.css';
import Navbar from 'react-bootstrap/Navbar';
import svgIcon from './navbaricon.svg';
import Nav from 'react-bootstrap/Nav';
const Topbar = (props) => {
return (
<Navbar className={styles.navbar}>
<Navbar.Brand className={styles.title} href="/">
<img
alt=""
src={svgIcon}
width="30"
height="30"
className="d-inline-block align-top"
/>{' '}Invsetment Dashboard
</Navbar.Brand>
<Navbar.Collapse id="responsive-navbar-nav">
<Nav className="me-auto" activeKey={props.path}>
<Nav.Link href="/" className={styles.link}><p>首頁</p></Nav.Link>
<Nav.Link href="/macroeconomics" className={styles.link}><p>總體經濟</p></Nav.Link>
</Nav>
</Navbar.Collapse>
</Navbar>
);
};
export default Topbar;
總之繞了好一大圈,終於將路徑資料傳遞到Navbar裡面了,架構上看起來稍微複雜了一些,不過是為了後續維護上的方便度,才使用這樣的架構,還算是可以接受。目前首頁還是沒有內容的,接下來就來做一下首頁吧~