本篇文章參考極客時間 React Router 教程
文章目錄
前言
最近在研究 React 的相關技術棧,隱隱約約有種感覺,現在的框架發展路線不再是隻提供框架,而是一種概念,一種生態,就像你用蘋果手機,你使用的不僅僅是蘋果的手機產品,它的背後有一套完整的解決方案在支持。首先你必須註冊蘋果賬號才能下載 app ,其次所有軟件又都是 IOS 提供的。
再舉個例子,學會 react ,相當於造出了 V12 的引擎,如果沒有配套生態的使用,那就是在用這臺引擎耕地。
所以只會使用 React 的時候,並不能把其中的精髓發揮到極致,唯一辦法就是,接受它的全部。
爲什麼使用React Router
因爲配置路由一般是小組長的工作,想要升值加薪,升爲組長,就必須要會。
當然,路由是提升用戶體驗的重要一環,當需要頁面切換而又不想重新加載新頁面的時候,就需要用到路由。同時還可以增強組織資源的語義,每個頁面的業務功能都是高內聚,低耦合的,通過 url 就可以將頁面進行很好的隔離。
基於路由配置進行資源組織的好處
- 實現業務邏輯的松耦合,
- 易於擴展,重構和維護
- 路由層面實現 Lacy Load
一、路由定義
1.1 路由實現基本架構
React Router 是在一個組件容器中,根據 url 來判斷當前應該顯示什麼樣的組件。
對應代碼如下:
const Home = () => <h1>Home</h1>;
const Hello = () => <h1>Hello</h1>;
const About = () => <h1>About</h1>;
...
<Router>
<div id="menu">
<ul>
<li><Link to="/home">Home</Link></li>
<li><Link to="/hello">Hello</Link></li>
<li><Link to="/about">About</Link></li>
</ul>
<div id="page_container">
<Route patch="/home" component={Home} />
<Route patch="/hello" component={Hello} />
<Route patch="/about" component={About} />
</div>
</div>
</Router>
上面 Link 標籤是 React Router 給我們提供的,當點擊這個 Link 的時候,url 會發生變化,但是頁面不會刷新,只是顯示對應的組件。這一點帶來的好處就是,當我們在瀏覽網頁的時候,點擊刷新後,我們還是在剛纔瀏覽的頁面,而不是被迫跳轉回首頁。
這個 Link 雖然 render 出來是一個連接的標誌,但是點擊的時候,並不會真的告訴瀏覽器,而是通過 React Router 來控制頁面變化。
1.2 React Router 特性
路由的概念是後端最先擁有的,其實就是 url 的對照表,類似書籍的目錄。選擇那個目錄,對應到哪個頁面。後端路由一般通過路由的配置表來定義,比如說 express 等。
React Router 作爲前端路由,有一些自己的特性。
1.2.1 聲明式路由定義
通過標籤定義,可以在任何地方使用。
const app = () => {
<div>
<nav>
<Link to="/home">Home</Link>
</nav>
<div>
<Route patch="/home" component={Home} />
</div>
</div>
}
1.2.2 動態路由
傳統服務端路由一旦定義好了,就是一個配置文件,是靜態的放在那裏,但是對於 React Router 來說它是動態路由,因爲只有當頁面 render 的時候,路由纔會被解析。
二、路由實現的三種方式
React Router 提供了三種路由的實現方式。
- URL 路徑
- hash 路由
- 內存路由
大部分的時候可以通過 URL 路徑實現 ,但是有些低版本瀏覽器不支持 url 改變後,頁面不刷新,這個時候就需要用到 hash 路由 。三種路由的使用方法基本一致,只有導入的時候名字不同而已,具體區別如下:
2.1 URL 路徑
這種方式是通過改變 URL 來進行頁面內容的改變,所以點擊不同的 Link 的時候,url地址會根據 Link 的設置而變化。
import React, { Component } from 'react';
//url路徑的導入名稱是 BrowserRouter
import {
BrowserRouter as Router,
Route,
Link
} from 'react-router-dom';
const Home = () => <h1>Home</h1>;
const Hello = () => <h1>Hello</h1>;
const About = () => <h1>About</h1>;
class Test extends Component {
render() {
return (
<Router>
<div id="menu">
<ul>
<li><Link to="/home">Home</Link></li>
<li><Link to="/hello">Hello</Link></li>
<li><Link to="/about">About</Link></li>
</ul>
<div id="page_container">
<Route patch="/home" component={Home} />
<Route patch="/hello" component={Hello} />
<Route patch="/about" component={About} />
</div>
</div>
</Router>
);
}
}
export default Test;
瀏覽器顯示情況如下,(當點擊 About 的時候)
2.2 hash 路由
這種方式爲了適配部分瀏覽器,不允許 URL 改變的時候,頁面不刷新。使用方法與上面一樣,只是導入名稱不同。
import React, { Component } from 'react';
// hash 路由的導入名稱是 HashRouter
import {
HashRouter as Router,
Route,
Link
} from 'react-router-dom';
...
瀏覽器地址部分也會有所變化,會有一個 # 在路由地址前。
2.3 內存路由
內存路由不是通過頁面地址進行存儲的,而是存在內存當中,進行保存。
import React, { Component } from 'react';
import { Route, Link } from 'react-router-dom';
// 內存路由的導入名稱是 MemoryRouter 並且是通過 react-router 導入的
import { MemoryRouter as Router } from 'react-router';
...
點擊不同 Link 的時候,URL 地址不變。
三、核心 API
- <Link> 普通連接,不會觸發瀏覽器刷新。
- <NavLink> 類似 Link 但是會添加當前選中狀態。
- <Prompt> 滿足條件時提示用戶是否離開當前頁面。
- <Redirect> 重定向當前頁面,例如登錄判斷。
- <Route> 路由配置的核心標記,路由匹配時顯示對應組件(此組件不排他,只要路由匹配,組件都會顯示)
- <Switch> 只顯示第一個匹配的路由。