1. 程式人生 > >從 React Router 談談路由的那些事

從 React Router 談談路由的那些事

React Router 是專為 React 設計的路由解決方案,在使用 React 來開發 SPA (單頁應用)專案時,都會需要路由功能,而 React Router 應該是目前使用率最高的。

React Router 並不是 Facebook 的 React 官方團隊開發的,但是據說有官方人員參與開發。React Router 的設計思想來源於 Ember 的路由,如果原來有用過 Ember 的路由,那麼應該對 React Router 不會陌生。

什麼是路由?

對於沒有開發過後端,也沒有開發過 SPA 的前端來說,「路由」這個名詞可能會讓人比較困惑,這裡的路由並不是指「硬體路由」,也不是網路七層協議中的「網路層路由」,但是其思想原理是一樣的。我儘量簡單通俗的介紹一下。

假如我們有一臺提供 Web 服務的伺服器的網路地址是:10.0.0.1,而該 Web 服務又提供了三個可供使用者訪問的頁面,其頁面 URI 分別是:

123 http://10.0.0.1/http://10.0.0.1/abouthttp://10.0.0.1/concat

那麼其路徑就分別是 //about/concat

當用戶使用 http://10.0.0.1/about

來訪問該頁面時,Web 服務會接收到這個請求,然後會解析 URI 中的路徑 /about,在 Web 服務的程式中,該路徑對應著相應的處理邏輯,程式會把請求交給路徑所對應的處理邏輯,這樣就完成了一次「路由分發」,這個分發就是通過「路由」來完成的。

前端路由

前端的路由和後端的路由在實現技術上不一樣,但是原理都是一樣的。在 HTML5 的 history API 出現之前,前端的路由都是通過 hash 來實現的,hash 能相容低版本的瀏覽器。如果我們把上面例子中提到的 3 個頁面用 hash 來實現的話,它的 URI 規則中需要帶上 #

123 http://10.0.0.1/http://10.0.0.1/#/abouthttp://10.0.0.1/#/concat

Web 服務並不會解析 hash,也就是說 # 後的內容 Web 服務都會自動忽略,但是 JavaScript 是可以通過 window.location.hash 讀取到的,讀取到路徑加以解析之後就可以響應不同路徑的邏輯處理。

history 是 HTML5 才有的新 API,可以用來操作瀏覽器的 session history (會話歷史)。基於 history 來實現的路由可以和最初的例子中提到的路徑規則一樣。

123 http://10.0.0.1/http://10.0.0.1/abouthttp://10.0.0.1/concat

使用者可能都察覺不到該訪問地址是 Web 服務實現的路由還是前端實現的路由。

從效能和使用者體驗的層面來比較的話,後端路由每次訪問一個新頁面的時候都要向伺服器傳送請求,然後伺服器再響應請求,這個過程肯定會有延遲。而前端路由在訪問一個新頁面的時候僅僅是變換了一下路徑而已,沒有了網路延遲,對於使用者體驗來說會有相當大的提升。

說了這麼多的「路由基礎」,該回頭來說說 React Router 了。

配置路由

使用 React Router 來配置上面例子中的三個頁面,每個頁面分別對應著一個 React Component。

/about 頁面的入口檔案 about.js

1234567891011 import React from'react';classAbout extendsReact.Component{render(){return(ThisisAbout page.);}};export defaultAbout;

/concat 頁面的入口檔案 concat.js

123456789 import React from'react';constConcat=()=>{return(ThisisConcat page.);};export defaultConcat;

/ 首頁對應的是 app.js,它也是整個 React Component 的入口檔案。

12345678910111213141516171819202122 import React from'react';import{Link}from'react-router';classApp extendsReact.Component{render(){return(React Router Demoby stylechen.comHomeAboutConcat{this.props.children})}};export defaultApp;

app.js 中的 Link 元件是 React Router 提供的元件,用於連結到相應頁面。如果直接使用 a 標籤的話相當於頁面跳轉了,而使用 Link 只是應用內的路由跳轉,頁面跳轉意味著先重新載入整個頁面,然後才是應用內部的路由跳轉。

index.js 中包含了 route 的配置,同時在該檔案中對 React Component 進行 render

1234567891011121314151617181920 import React from'react';import ReactDOM from'react-dom';import createBrowserHistory from'history/lib/createBrowserHistory';import App from'./component/app';import About from'./component/about';import Concat from'./component/concat';import{Router,Route}from'react-router';consthistory=createBrowserHistory();constrouter=();ReactDOM.render(router,document.getElementById('root'));

Route 元件就是用於配置路由,path 屬性用於配置路徑,component 就是對應的 React Component。

Route 元件支援巢狀,巢狀時子元件的路徑可以繼承父元件的路徑,上面的 about 巢狀後就成了 /about,當然也可以直接以根路徑為開頭。

此時再看看 app.js 中的 this.props.childrenAboutConcat 兩個頁面元件其實就是以這種形式插入到父元件中,只是插入的時候用 React Router 提供的元件再包裝了一下使它們可以支援路由。

Router元件還有一個重要的屬性,那就是history,這可以配置使用history來實現路由,如果沒有配置這個屬性則預設使用hash

路由引數

假如我們有很多 list 頁面,這些頁面除了動態內容不同,其他的頁面部分都相同,這個時候需要怎麼配置路由和元件呢?

這種場景就需要用到路由的引數功能,增加一條包含引數的路由配置。

1 import List from'./component/list';

注意 path 屬性中的 :id 就是該路由的引數(param)。再來看看 List 頁面的元件。

123456789101112131415 import React from'react';classList extendsReact.Component{render(){return(ThisisList page.Thelistpageidis {this.props.params.id});}};export defaultList;

List 元件中,可以直接通過 this.props.params.id 來訪問實際的引數值(這裡的id key 就和定義路徑的 :id 相對應),React Router 將路由的資料都通過 props 傳遞給了頁面元件,這樣就可以非常方便的訪問路由相關的資料了。

元件的生命週期

每個 React Component 都有生命週期,按照常規的策略,當呼叫父元件的 render 的時候,會將所有的頁面子元件也進行 render,這種邏輯顯然不合理了。那麼當一個 React 的應用有了路由功能後,它的生命週期會如何處理呢?

當切換路由的路徑的時候才去 render 對應的頁面元件,給 About 繫結兩個元件裝載和解除安裝的事件,就可以測試出來了。

12345678910111213141516171819 import React from'react';classAbout extendsReact.Component{componentDidMount(){console.log('mount');}componentWillUnmount(){console.log('un mount');}render(){return(ThisisAbout page.);}};export defaultAbout;

在切換到 /about 頁面的時候,會打印出 mount,而當離開頁面的時候會打印出 un mount。路由的這種進入時裝載元件離開時解除安裝元件的策略就可以做到合理利用「資源」,不會一下把所有的元件都裝載進來使記憶體佔用飆升,也不會離開時沒有解除安裝而時記憶體洩漏。

React Router 還有很多比較方便 API,這裡不一一列舉,通過上面的文章基本能覆蓋到常規的使用場景了,想了解更多使用方面檢視 專案主頁

本文的 demo 程式碼都已經託管在 github 上了,可以自己下載到本地瀏覽。

相關推薦

React Router 談談路由那些

React Router 是專為 React 設計的路由解決方案,在使用 React 來開發 SPA (單頁應用)專案時,都會需要路由功能,而 React Router 應該是目前使用率最高的。 React Router 並不是 Facebook 的 React 官方團隊開發的

react-router v4 路由規則解析

前言 react-router升級到4之後,跟前面版本比有了很大的差別。 例如包的拆分,動態路由等詳細的差別就不說了,各位大神的總結也很到位,詳細可以點選看看,All About React Router 4這篇文章。 此外還有個差別是路由規則的變化。 一直有著上個版本的習慣,所以稍微複雜的路由,配起來的時

React-Router 獲取路由引數

慢慢整理哈! componentWillMount() { let visitor = this.props.location.search; visitor = visitor.split('=')[1]; this.setState({visitor:visit

React-router-dom路由的使用

React-router-dom的入門使用 1.專案引入react-router-dom 安裝: npm install react-router-dom --save 引入: import { BrowserRouter as Router, Rout

用 Yarn + webpack 2 + Babel 架設 React 環境 « 關於網路那些...

Webpack 是一個 module 整合工具,用來將javascript 打包成一支讓瀏覽器能夠執行的 bundle.js。 看似簡單,但其實功能非常強大

React-static « 關於網路那些...

React Static 是一個漸進式靜態網站生成工具,也是一個在server端渲染React 應用架構的框架,輕量且強大的架構可以滿足 SEO,完善的網站效能及

win7到win10的那些~

    為啥要換成win10?我之前可一直都是win7粉,在知乎上搜了一波win10的體驗之後,感覺相對於win7而言更好看更快,再加之現在win10對大部分軟體都相容了,所以就轉粉了,聽說**win10 LTSB長期

react-router v4 路由跳轉 動態引數

react-router v4 路由跳轉 react-router v4 路由傳參 使用 withRouter withRouter高階元件,提供了history讓你使用~ import React

淺談關於react router 許可權那些

背景 近期做了一個 spa的單獨專案中,有個需求就是希望根據登入人來看下,這個人是不是有許可權進入當前頁面。雖然服務端做了進行介面的許可權,但是每一個路由載入的時候,都要去請求這個介面太浪費了。 需要考慮的 登入授權,使用者沒有登入只能訪問登入頁面,如果處於登入狀態則跳轉到當前使用者的預設首頁

路由原理出發,深入閱讀理解react-router 4.0的原始碼

  react-router等前端路由的原理大致相同,可以實現無重新整理的條件下切換顯示不同的頁面。路由的本質就是頁面的URL發生改變時,頁面的顯示結果可以根據URL的變化而變化,但是頁面不會重新整理。通過前端路由可以實現單頁(SPA)應用,本文首先從前端路由的原

react-router打包後無法通過路由進入到頁面

裏的 col ces con def gin cnblogs style 數據 react-router打包後無法通過路由進入到頁面,是因為當我們使用react-router-dom裏的BrowserRouter as Router時,是用瀏覽器history對象的方法去請

react-router搭配react-redux無法監聽路由變化的問題

不必要 默認 cti 傳遞 通過 nbsp fun urn style 在react中,要將react組件連接到redux中,通常會這樣包裝組件 class Home extends Component { } function select(state)

react-router v3 版本升到 v4 版本,升級小記

必須 寫作 his 瀏覽器 down red isp 跳轉 mark react-router v4 跟 react 一樣拆成了兩部分,核心的 react-router 和依運行環境而定的 react-router-dom 或 react-router-native(跟

React Router 4.0 ---- 嵌套路由和動態路由

屬性 效果 進一步 column direction 導航欄 ace wid class   嵌套路由,從廣義上來說,分為兩種情況:一種是每個路由到的組件都有共有的內容,這時把共有的內容抽離成一個組件,變化的內容也是一個組件,兩種組件組合嵌套,形成一個新的組件。另一種是子路

react-router(不同組件之間傳遞路由

react router 不同組件 圖解: 代碼: // less require (‘./static/less/index.less‘) // 核心 var React = require(‘react‘) var ReactDom = require(‘react-dom‘) var Rea

webpack4.X + react-router 路由跳轉

mod rep reac 安裝 靜態資源 default lena serve tel webpack4.X react-router 環境準備工作:windows7、webStorm 2017.1.4、Nodejs 8.7.0、npm 5.4.2 PS:安裝的時我們

react-router 4.x 路由按需加載

HA sync tac roo ID rem route RR fig react-router 4 代碼分割(按需加載) 官方文檔 https://serverless-stack.com/chapters/code-splitting-in-create-react-

腳手架初始化 react 項目 react-router 路由

3.2 git color IV bsp 腳手架 out star ui框架 1,首先創建 npm install -g create-react-app create-react-app my-app //my-app 項目名稱 cd my-app //

react router路由傳參

都是 HA mat this one lin 刷新 sta ram 今天,我們要討論的是react router中Link傳值的三種表現形式。分別為通過通配符傳參、query傳參和state傳參。 ps:進入正題前,先說明一下,以下的所有內容都是在react-router

react-router-dom實現全局路由登陸攔截

狀態 統一管理 hist pan erro extend urn app.js cati   相比與vue的路由集中式管理,能夠很好的進行統一的路由操作,react的路由看起來更亂,想要進行像vue的全局路由管理不是那麽得心應手。在我們的項目中,有很多頁面是需要登陸權限驗證