React Router 是一個基於 React 之上的強大路由庫,它可以讓你嚮應用中快速地添加視圖和數據流,同時保持頁面與 URL 間的同步。
不使用react-router時的路由跳轉方案:
import React from 'react';
// 引入頁面
import Index from './pages/Index'; // 首頁
import Article from './pages/Article'; // 文章頁
import About from './pages/About'; // 關於頁
class App extends React.Component {
constructor() {
super();
this.state = {
path: ''
}
}
componentDidMount() { // 生命週期:加載完畢
window.addEventListener('hashchange',()=>{ // 監聽url錨點(#)變化
this.setState({
path: window.location.hash.substr(1)
})
})
}
render() {
let child;
switch (this.state.path) {
case '':
child = <Index></Index>
break;
case 'article':
child = <Article></Article>
break;
case 'about':
child = <About></About>
break;
default:
child = <Index></Index>
}
return (
<div>
<a href="#">首頁</a>
<a href="#article"> | 文章頁</a>
<a href="#about"> | 關於</a>
{child}
</div>
)
}
}
export default App;
這種方式面對頁面簡單,數量少的還能接受,程序大了之後,便難於維護與編寫。
使用react-router:
1、安裝
當前案例使用的版本爲:
"dependencies": {
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.5.0",
"@testing-library/user-event": "^7.2.1",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-router-dom": "^5.2.0",
"react-scripts": "3.4.1"
}
局部安裝 react-router-dom
npm install react-router-dom -s
2、介紹react-router-dom中的幾個主要組件和方法:
BrowderRouter:組件:用常規的URL路徑。這些通常是外觀最好的URL,但是它們要求正確配置服務器。具體來說,您的Web服務器需要在所有由React Router客戶端管理的URL上提供相同的頁面。
HashRouter: 組件:將當前位置存儲在URL的hash一部分中,因此URL看起來像http://example.com/#/your/page
。由於哈希從不發送到服務器,因此這意味着不需要特殊的服務器配置。
Switch:組件:常常會用來包裹Route,它裏面不能放其他元素,用來只顯示一個路由。Switch用於匹配查找path,以匹配顯示Route中的組件。
Route:組件:被包裹在Switch裏面,放置被path匹配時顯示的組件,被Switch查找。
Link:導航組件:提供超鏈接控制路由跳轉,to屬性可以是一個字符串(單純path路徑,也可以是一個對象)
// to對象屬性
pathname: 路由字符串
search: 路由查找參數,如:?test=1
hash: 錨點字符串,會添加到路由尾部,如:#test
state: 額外參數,可以是一個對象,如:{name: 'test'}
NavLink:導航組件:是Link的特殊版本,他可以有更多的功能,可以設置更多的屬性。
activeClassName(string):設置選中樣式,默認值爲active
activeStyle(object):當元素被選中時,爲此元素添加樣式
exact(bool):爲true時,只有當導致和完全匹配class和style纔會應用
strict(bool):爲true時,在確定爲位置是否與當前URL匹配時,將考慮位置pathname後的斜線
isActive(func)判斷鏈接是否激活的額外邏輯的功能
Redirect:組件:當有沒有匹配到任何路由時,重定向到指定路徑,一般放在Switch裏的最底部。
<Redirect to="/"></Redirect>
useRouteMatch:方法:獲取組件匹配的路由對象。
isExact:是否嚴格模式
params:訪問當前組件的路由攜帶參數
path:訪問當前組件的路由匹配規則
url:訪問當前組件的實際匹配的路由(實際顯示的路由)
useParams:訪問當前組件的路由攜帶參數,即 useRouteMatch 中的params。
更多更標準的解釋可查看: 官方文檔API
3、開始使用
示例:
import React from 'react';
import './App.css';
// 其中BrowserRouter 引入後改爲別名Router,改別名的原因是爲了易維護,不與使用HashRouter時發生衝突,而需要在此修改
import {BrowserRouter as Router, Switch, Route, Link} from 'react-router-dom';
// 引入頁面
import Index from './pages/Index'; // 首頁
import Article from './pages/Article'; // 文章頁
import About from './pages/About'; // 關於頁
class App extends React.Component {
render() {
return (
<div>
<Router>
<Link to="/">首頁</Link>
<Link to="/article">文章頁</Link>
<Link to="/about">關於頁</Link>
<Switch>
<Route path="/about"> {/*路由匹配時將會渲染其中的組件*/}
<About />
</Route>
<Route path="/article"> {/*如果只是顯示組件,可以這樣寫:<Route path="/article" component={Article} />*/}
<Article />
</Route>
<Route path="/">
<Index />
</Route>
</Switch>
</Router>
</div>
)
}
}
export default App;
4、嵌套路由
以上一個示例中的Article組件修改爲例:
示例包含次級路由訪問、動態路由訪問。注意:在JSX中註釋需要 {/**/} 包裹
import React from 'react'
import { useRouteMatch, useParams, Link, Route, Switch} from 'react-router-dom'
function Page(){
let match = useRouteMatch(); // 獲取當前組件匹配的路由
return (
<div>
<h1>這是文章頁</h1>
<Link to={`${match.url}/hot`}>最熱文章</Link> {/*查看最熱文章*/}
<Link to={`${match.url}/latest`}> | 最新文章</Link> {/*查看最熱文章*/}
<Link to={`${match.url}/1`}> | 文章1</Link> {/* 查看id爲1的文章*/}
<Link to={`${match.url}/2`}> | 文章2</Link> {/*查看id爲2的文章*/}
<Switch>
<Route path={`${match.path}/hot`}> {/*匹配最熱文章*/}
<h2>這是最熱文章</h2>
</Route>
<Route path={`${match.path}/latest`}> {/*匹配最新文章*/}
<h2>這是最新文章</h2>
</Route>
<Route path={`${match.path}/:id`}> {/*匹配動態id查看文章,匹配文章id詳情組件*/}
<ArticleDetail></ArticleDetail>
</Route>
</Switch>
</div>
)
}
function ArticleDetail() {
let { id } = useParams(); // 獲取參數id
return (
<h1>這是文章{id}</h1>
)
}
export default Page;
官方英文文檔:https://reacttraining.com/react-router/web/guides/quick-start
注:個人筆記,不作標準答案,僅供參考,不喜勿噴。