您好,登錄后才能下訂單哦!
小編給大家分享一下怎么實(shí)現(xiàn)react-router,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
一、react-router依賴(lài)基礎(chǔ)-history
1、History整體介紹
對(duì)于history 來(lái)說(shuō),它是獨(dú)立的第三方 js 庫(kù),是可以用來(lái)兼容在不同環(huán)境和瀏覽器下歷史記錄的管理,而且還擁有統(tǒng)一的 API,在 history中主要分為這幾類(lèi):
老瀏覽器的 history : 主要通過(guò)hash來(lái)實(shí)現(xiàn),對(duì)應(yīng)createHashHistory
。
高版本瀏覽器: 通過(guò) html5 里面的 history,對(duì)應(yīng)createBrowserHistory
。
node 環(huán)境下: 主要存儲(chǔ)在 memeory 里面,對(duì)應(yīng)createMemoryHistory
。
對(duì)于這三個(gè)類(lèi),在不同的環(huán)境中還提供了三個(gè)PAI,而且他們有一些相同性質(zhì)的操作,就是將公共文件 createHistory 抽象化,代碼如下所示:
// 內(nèi)部的抽象實(shí)現(xiàn)
function createHistory(options={}) {
...
return {
listenBefore, // 內(nèi)部的hook機(jī)制,可以在location發(fā)生變化前執(zhí)行某些行為,AOP的實(shí)現(xiàn)
listen, // location發(fā)生改變時(shí)觸發(fā)回調(diào)
transitionTo, // 執(zhí)行l(wèi)ocation的改變
push, // 改變location
replace,
go,
goBack,
goForward,
createKey, // 創(chuàng)建location的key,用于唯一標(biāo)示該location,是隨機(jī)生成的
createPath,
createHref,
createLocation, // 創(chuàng)建location
}
}
對(duì)于上面我們有涉及到的 history 內(nèi)部最基礎(chǔ)的方法分別是:createHashHistory
、createBrowserHistory
、createMemoryHistory
對(duì)于這三個(gè)方法他們只是覆蓋了其中的一些方法,值得注意的是,在這個(gè)時(shí)候的location
跟瀏覽器原生的location
是不相同的,然而這個(gè)最大的區(qū)別就在于里面多了key
字段,history
內(nèi)部通過(guò)key
來(lái)進(jìn)行location
的操作;代碼如下所示:
function createLocation() {
return {
pathname, // url的基本路徑
search, // 查詢(xún)字段
hash, // url中的hash值
state, // url對(duì)應(yīng)的state字段
action, // 分為 push、replace、pop三種
key // 生成方法為: Math.random().toString(36).substr(2, length)
}
}
2、 內(nèi)部解析
對(duì)于我們提及到的三個(gè) API 的實(shí)現(xiàn)方法如下:
createBrowserHistory
: 利用 HTML5 里面的 history。
createHashHistory
: 通過(guò) hash 來(lái)存儲(chǔ)在不同狀態(tài)下的 history 信息。
createMemoryHistory
: 在內(nèi)存中進(jìn)行歷史記錄的存儲(chǔ)。
3、 執(zhí)行URL前進(jìn)
這三個(gè)方法在執(zhí)行 URL 的方法如下所示:
createBrowserHistory
: pushState、replaceState。
createHashHistory
: location.hash=***
location.replace()
。
createMemoryHistory
: 在內(nèi)存中進(jìn)行歷史記錄的存儲(chǔ)。
對(duì)于偽代碼的實(shí)現(xiàn)如下所示:
// createBrowserHistory(HTML5)中的前進(jìn)實(shí)現(xiàn)
function finishTransition(location) {
...
const historyState = { key };
...
if (location.action === 'PUSH') ) {
window.history.pushState(historyState, null, path);
} else {
window.history.replaceState(historyState, null, path)
}
}
// createHashHistory的內(nèi)部實(shí)現(xiàn)
function finishTransition(location) {
...
if (location.action === 'PUSH') ) {
window.location.hash = path;
} else {
window.location.replace(
window.location.pathname + window.location.search + '#' + path
);
}
}
// createMemoryHistory的內(nèi)部實(shí)現(xiàn)
entries = [];
function finishTransition(location) {
...
switch (location.action) {
case 'PUSH':
entries.push(location);
break;
case 'REPLACE':
entries[current] = location;
break;
}
}
4、 檢測(cè)URL回退
三個(gè)方法的使用方式如下所示:
createBrowserHistory
: popstate
。
createHashHistory
: hashchange
。
createMemoryHistory
: 因?yàn)槭窃趦?nèi)存中操作,跟瀏覽器沒(méi)有關(guān)系,不涉及 UI 層面的事情,所以可以直接進(jìn)行歷史信息的回退。
偽代碼的實(shí)現(xiàn)方式如下所示:
// createBrowserHistory(HTML5)中的后退檢測(cè)
function startPopStateListener({ transitionTo }) {
function popStateListener(event) {
...
transitionTo( getCurrentLocation(event.state) );
}
addEventListener(window, 'popstate', popStateListener);
...
}
// createHashHistory的后退檢測(cè)
function startPopStateListener({ transitionTo }) {
function hashChangeListener(event) {
...
transitionTo( getCurrentLocation(event.state) );
}
addEventListener(window, 'hashchange', hashChangeListener);
...
}
// createMemoryHistory的內(nèi)部實(shí)現(xiàn)
function go(n) {
if (n) {
...
current += n;
const currentLocation = getCurrentLocation();
// change action to POP
history.transitionTo({ ...currentLocation, action: POP });
}
}
5、 state的存儲(chǔ)
對(duì)于 state 的存儲(chǔ)來(lái)說(shuō),我們?cè)跒榱司S護(hù)它的狀態(tài)的時(shí)候,我們會(huì)將其存儲(chǔ)在我們的 sessionStorage 中,代碼如下所示:
// createBrowserHistory/createHashHistory中state的存儲(chǔ)
function saveState(key, state) {
...
window.sessionStorage.setItem(createKey(key), JSON.stringify(state));
}
function readState(key) {
...
json = window.sessionStorage.getItem(createKey(key));
return JSON.parse(json);
}
// createMemoryHistory僅僅在內(nèi)存中,所以操作比較簡(jiǎn)單
const storage = createStateStorage(entries); // storage = {entry.key: entry.state}
function saveState(key, state) {
storage[key] = state
}
function readState(key) {
return storage[key]
}
二、react-router的基本原理
我們先來(lái)看一張 react-router 原理圖,如下所示:
在這張流程中我們可以知道,在 react-router 中,URL
對(duì)應(yīng)Location
對(duì)象,而UI是由 react components
來(lái)決定的,這樣就轉(zhuǎn)變成location
與components
之間的同步問(wèn)題。
三、react-router具體實(shí)現(xiàn)
通過(guò)上面的知識(shí)我們知道,react-router 在 history 這個(gè)庫(kù)類(lèi)的基礎(chǔ)上實(shí)現(xiàn)URL和UI同步的話(huà)分為這另個(gè)層次來(lái)描述實(shí)現(xiàn)的具體步驟:
1、 組件層面描述實(shí)現(xiàn)過(guò)程
我們先來(lái)看看下面這張流程圖:
在這個(gè)流程圖中我們知道最主要的 component 是Router
RouterContext
Link
,對(duì)于history
庫(kù)的話(huà)只有起到了中間橋梁的作用。
2、API層面描述實(shí)現(xiàn)過(guò)程
我們?cè)?API 這個(gè)層次中我們可以通過(guò)下面這張流程圖了解,如下所示:
小結(jié):
對(duì)于react-router來(lái)說(shuō)目前是比較受歡迎的,而且也在很多的項(xiàng)目中被大量的使用,它的有點(diǎn)可以分為下面幾點(diǎn):
風(fēng)格: 與React融為一體,專(zhuān)為 react 量身打造,編碼風(fēng)格與 react 保持一致,例如路由的配置可以通過(guò) component 來(lái)實(shí)現(xiàn)。
簡(jiǎn)單: 不需要手工維護(hù)路由 state,使代碼變得簡(jiǎn)單。
強(qiáng)大: 強(qiáng)大的路由管理機(jī)制,體現(xiàn)在如下方面。
路由配置: 可以通過(guò)組件、配置對(duì)象來(lái)進(jìn)行路由的配置。
路由切換: 可以通過(guò)<Link>
Redirect
進(jìn)行路由的切換。
路由加載: 可以同步記載,也可以異步加載,這樣就可以實(shí)現(xiàn)按需加載。
使用方式: 不僅可以在瀏覽器端的使用,而且可以在服務(wù)器端的使用。
當(dāng)然 react-router 并不是說(shuō)都沒(méi)有缺點(diǎn),它的缺點(diǎn)就是 API 比較不太穩(wěn)定。
以上是“怎么實(shí)現(xiàn)react-router”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。