這篇文章要跟大家介紹的內容是關於React Router中的核心history庫的詳細分析,有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。
使用React開發稍微複雜一點的應用,React Router幾乎是路由管理的唯一選擇。雖然React Router經歷了4個大版本的更新,功能也越來越豐富,但無論怎麼變,它的核心都依賴history函式庫卻一直沒變。下面我們來了解下這個在github上有4k 星的庫到底提供了什麼功能。
聊到history函式庫,是不是覺得這個字有點熟?不錯,HTML5規格裡面,也新增了一個同名的history物件。下面我們來看看這個history物件用來解決什麼問題。
在jQuery統治前端的年代,透過ajax請求無刷新更新頁面是當時相當流行的頁面處理方式,SPA的雛形就是那時演化出來的。為了標示頁面發生的變化,方便刷新後仍能顯示正確的頁面元素,一般會透過改變url的hash值來唯一定位頁面。但這會帶來另一個問題:使用者無法使用前進/後退來切換頁面。
為了解決這個問題,history物件應運而生。當頁面的url或hash發生變化的時候,瀏覽器會自動將新的url push到history物件中。 history物件內部會維護一個state數組,記錄url的變化。在瀏覽器進行前進/後退操作的時候,實際上就是呼叫history物件的對應方法(forward
/back
),取出對應的state,從而進行頁面的切換。
除了操作url,history物件也提供2個不用透過操作url也能更新內部state的方法,分別是pushState
和replaceState
。也可以將額外的資料存到state中,然後在onpopstate
事件中再透過event.state
取出。如果希望對history物件作更深入的理解,可以參考 這裡,和這裡。
我們再回過頭來看history函式庫。它本質上做了以下4件事情:
借鑒HTML5 history物件的概念,在其基礎上又擴展了一些功能
提供3種類型的history:browserHistory,hashHistory,memoryHistory,並保持統一的api
支援發布/訂閱功能,當history發生改變的時候,可以自動觸發訂閱的函數
提供跳躍攔截、跳轉確認和basename等實用功能
#再比較一些兩者api的異同。以下是history函式庫的:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
以下是HTML5 history物件的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
從對比中可以看出,兩者的關係是非常密切的,history函式庫可以說是history物件的超集,是功能更強大的history物件。
下面,我們以三種history類型中的一種,hashHistory為例,來分析下history的源碼,看看它都乾了些什麼。先看下它是怎麼處理hash變更的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
|
以上就是處理被動的hash變更的邏輯,一句話概括就是:訂閱hash變更事件,判斷是否確實要變更,如需變更則更新自己的屬性,通知訂閱者,不需變更則回退到之前的狀態。
下面再看下transitionManager做了什麼,重點看發布/訂閱相關內容,忽略用戶確認跳轉相關內容。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
這裡的程式碼一目了然,就是維護一個訂閱者列表,當hash變更的時候通知到相關的函數。
以上是hash改變的時候被動更新相關的內容,下面再看下主動更新相關的程式碼,以push
為例,replace
大同小異。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
在瀏覽器進行前進後退操作時,history庫實際上是透過操作HTML5 history物件實現的。
1 2 3 4 5 6 7 8 9 10 |
|
當呼叫window.history.go
的時候,hash會發生變化,進而觸發hashchange事件,然後history庫再將變更通知到相關的訂閱者。
本文對React Router核心依賴history函式庫進行了比較深入的介紹。從HTML5新增的history物件講起,比較了它跟history庫千絲萬縷的關係,並以hashHistory為例子詳細分析了其程式碼的實作細節。
最後,我們再來回顧history函式庫做了哪些事情:
#借用HTML5 history物件的概念,在其基礎上又擴充了一些功能
提供3種類型的history:browserHistory,hashHistory,memoryHistory,並保持統一的api
支援發布/訂閱功能,當history發生改變的時候,可以自動觸發訂閱的函數
提供跳轉攔截、跳轉確認和basename等實用功能
雖然history庫是React Router的核心依賴,但它跟React本身並沒有依賴關係。如果你的專案中有操作history的場景,也可以將其引入專案中來。
相關建議:
HTML5如何解決margin-top的塌陷問題(附程式碼)
HTML5中標籤和常用規則有哪些? html5標籤以及規則的介紹
以上是React Router中的核心history函式庫的詳細分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!