- 深入理解React Router:從原理到實踐
- 李楊韜
- 1855字
- 2021-04-16 16:10:39
2.1 history庫概述
history庫為React Router提供了history對象,history對象提供了相關(guān)的地址監(jiān)聽、跳轉(zhuǎn)方法等。history對象在React Router中負責與“外部”的URL交互,其在React Router中發(fā)揮著非常重要的作用。
history庫提供了3類歷史對象的創(chuàng)建工廠函數(shù),分別是createBrowserHistory、createHashHistory和createMemoryHistory。
history對象在React Router中通常為單例形式,創(chuàng)建history對象的方法非常簡單,通常為調(diào)用相關(guān)的工廠create方法。

此外,createHashHistory方法和createMemoryHistory方法也可以創(chuàng)建history對象。由createBrowserHistory方法與createHashHistory方法創(chuàng)建的history對象依賴于瀏覽器運行環(huán)境;而調(diào)用createMemoryHistory方法創(chuàng)建的history對象可獨立于瀏覽器,在內(nèi)存中運行。
3類歷史對象都提供了一致的能力與接口,除了通用能力,各歷史對象對不同的外界環(huán)境也有著不同的能力。首先是通用能力部分,各歷史對象都具備:
·監(jiān)聽外界地址變化的能力。
·獲取當前地址的能力。
·增加和修改歷史棧的能力。
·在棧中移動當前歷史棧指針的能力。
·阻止跳轉(zhuǎn),以及定義跳轉(zhuǎn)提示的能力。
·獲取當前歷史棧長度及最后一次導航行為的能力。
·轉(zhuǎn)換地址對象的能力。
其次,各歷史對象也有著自身獨有的能力。
(1)browserHistory:
·可提供基準地址。
·可設置強刷模式。
·歷史棧標志符長度(keyLength)控制。
(2)hashHistory:
·可設置不同的hash模式(hashType)。
·可提供基準地址。
(3)memoryHistory:
·訪問整個歷史棧的能力。
·設置初始歷史地址及初始棧指針的能力。
·獲取當前棧指針的能力。
·歷史棧標志符長度(keyLength)控制。
·導航確認能力(canGo)。
值得一提的是,歷史棧標志符長度控制與提供基準地址的能力由于使用較少,可能在未來某個history版本中被移除。
對于browserHistory、hashHistory及memoryHistory,它們的通用能力可用同樣的history對象類型進行描述。

對于創(chuàng)建歷史對象的工廠方法,createBrowserHistory、createHashHistory及createMemoryHistory都可以傳入配置對象,配置對應的歷史對象的行為。歷史對象都可以傳入getUserConfirmation跳轉(zhuǎn)確認函數(shù):

getUserConfirmation跳轉(zhuǎn)確認函數(shù)通常用于在用戶操作流程沒有結(jié)束又產(chǎn)生導航時提醒用戶。對于getUserConfirmation跳轉(zhuǎn)確認函數(shù),其需要與history.block配合使用。history.block不與具體歷史對象相關(guān),對browserHistory、hashHistory和memoryHistory都通用。
history.block接受不傳入?yún)?shù),或者傳入一個string、boolean類型的參數(shù)或一個prompt 函數(shù)。當調(diào)用history.block時,任何導航包括瀏覽器的前進或后退行為都將被阻止,或者以某種形式提示用戶確認導航。此時,內(nèi)容區(qū)域不會發(fā)生變化。如果需要解綁history.block,則可以調(diào)用history.block返回的注銷函數(shù)。當調(diào)用注銷函數(shù)后,history將不會阻止跳轉(zhuǎn)行為。history.block的函數(shù)簽名如下,返回一個注銷函數(shù):
當prompt為boolean類型時,若為true,則不會阻止路由跳轉(zhuǎn);若為false,則阻止路由跳轉(zhuǎn)。當prompt為string類型時,默認彈出系統(tǒng)的prompt,一般為window.confirm。如果創(chuàng)建history時傳入了getUserConfirmation,則使用傳入的prompt。如果彈出系統(tǒng)的prompt,則會根據(jù)彈框返回結(jié)果進行路由控制,當在彈框中選擇“確定”按鈕時,則不進行阻止,按路由跳轉(zhuǎn)預期執(zhí)行;當在彈框中選擇“取消”按鈕時,則會阻止路由跳轉(zhuǎn)。如下面示例所示:


在上例中,若單擊“阻止跳轉(zhuǎn)”按鈕,則在調(diào)用history.block函數(shù)后,所有的跳轉(zhuǎn)導航都會提示“是否繼續(xù)?”,如圖2-1所示。只有當調(diào)用history.block返回的解除函數(shù)后,才會解除跳轉(zhuǎn)提示。注意,上例使用了ReactHooks,關(guān)于React Hooks部分將在第3章介紹。

圖2-1 跳轉(zhuǎn)確認彈框提示
在history.block參數(shù)列表中,允許傳入prompt函數(shù),prompt函數(shù)的類型為TransitionPromptHook:

參數(shù)列表中的第一個參數(shù)為要導航到的location地址;第二個參數(shù)為調(diào)用導航時對應的action,為“PUSH”、“REPLACE”或“POP”。
當傳入的prompt函數(shù)為TransitionPromptHook類型時,可以對跳轉(zhuǎn)阻止與否進行判斷,最終將根據(jù)函數(shù)的返回值情況決定。當函數(shù)返回false時,將阻止跳轉(zhuǎn);當函數(shù)返回undefined或true時,將不進行阻止。如果返回的是字符串,則默認使用window.confirm進行彈框確認,彈框的提示內(nèi)容即返回的字符串;同樣,如果創(chuàng)建history時傳入了getUserConfirmation,則將使用傳入的getUserConfirmation進行提示。當使用默認的window.confirm進行彈窗提示時,若單擊“確定”按鈕,則進行正常導航;若單擊“取消”按鈕,則阻止跳轉(zhuǎn)。對于getUserConfirmation,其類型為:

當調(diào)用callback(true)時,將允許導航跳轉(zhuǎn);當調(diào)用callback(false)時,導航跳轉(zhuǎn)將不會生效。
在browserHisotry和hashHistory默認提供的getUserConfirmation跳轉(zhuǎn)確認函數(shù)內(nèi)部,都使用了window.confirm進行彈窗確認,其實現(xiàn)的getUserConfirmation為:

也可自行定義彈框,如:

對于3類歷史對象通用的history.action,其意義為最后一次導航的導航行為,其值主要有“PUSH”、“REPLACE”和“POP”?!癙USH”表示上次導航行為是入棧行為,即增加歷史棧記錄。“REPLACE”表示上次導航行為是替換歷史棧行為,即修改歷史棧記錄?!癙OP”為調(diào)用函數(shù)history.go、history.goBack、history.goForward或者單擊瀏覽器的“前進”或“后退”按鈕時對應的導航行為,類似于popstate事件。其特點是僅移動棧指針,不對棧的記錄產(chǎn)生影響,其導航行為也應為“POP”。關(guān)于棧指針的移動可查看1.3節(jié)。
history.length表示歷史棧的長度,通常與window.history.length一致。
browserHisotry與hashHistory都有的basename為history實例的基準路徑。當創(chuàng)建history傳入basename時,最終生效的路徑為basename加上函數(shù)中的導航路徑。要注意,從history得到的路徑中不包含basename,basename僅生效于瀏覽器真實URL中。以browserHistory為例:


對于瀏覽器路徑location,也會剝除basename部分:

注意,basename會忽略大小寫:

- OpenShift開發(fā)指南(原書第2版)
- INSTANT OpenCV Starter
- Python量化投資指南:基礎、數(shù)據(jù)與實戰(zhàn)
- Pandas Cookbook
- Hands-On Data Structures and Algorithms with JavaScript
- Vue.js 3.x從入門到精通(視頻教學版)
- 算法訓練營:入門篇(全彩版)
- 軟件測試工程師面試秘籍
- 名師講壇:Spring實戰(zhàn)開發(fā)(Redis+SpringDataJPA+SpringMVC+SpringSecurity)
- 程序是怎樣跑起來的(第3版)
- Learning FuelPHP for Effective PHP Development
- PySide 6/PyQt 6快速開發(fā)與實戰(zhàn)
- Python算法指南:程序員經(jīng)典算法分析與實現(xiàn)
- Learning R for Geospatial Analysis
- 新一代SDN:VMware NSX 網(wǎng)絡原理與實踐