弁言
在運用react做龐雜的spa開闢中,開闢中必不可少的就是react-router,它運用Lerna治理多個堆棧, 在browser端常運用的幾個以下所示
- react-router 供應了路由的通用中心功用,輕易搞混的就是他和react-router-dom的區分,區分就是react-router-dom中多了Link BrowserRouter 如許的 DOM 類組件,至於router和route都是一樣的。
- react-router-dom 瀏覽器端運用的router
- react-router-redux 和redux集成運用時會用到
react-router中路由分類
BrowserRouter
基於html5供應的,history API(pushState, replaceState 和 popstate 事宜) 來堅持 UI 和 URL 的同步。大抵流程就是運用history.pushState塞歷史記錄到瀏覽器中,監聽window.onpopstate事宜,url變化的時刻render對應組件
HashRouter
HashRouter 是一種特定的 <Router>, HashRouter 運用 URL 的 hash (比方:window.location.hash) 來堅持 UI 和 URL 的同步。大抵流程是直接給window.location.hash賦值,監聽hashchange事宜,hash變化時,render對應的組件
MemoryRouter
保留'url'歷史記錄在內存中,在demo測試或許 React Native等非browser環境下運用
StaticRouter
服務端襯着中會用到
路由運用
就拿 HashRouter 運用來作為示例, 別的運用形式上相似,多說一句話Hash除了本日說的路由用處以外,還能夠做錨點定位。
import React, { Component } from 'react';
import {BrowserRouter as Router, Route, Link,Switch,Redirect} from 'react-router-dom'
class App extends Component {
render() {
return (
<Router>
<div>
<div>
<li><Link to='/'>home </Link></li> //link 實質完成實在就是一個a鏈接
<li><Link to='/about'>about</Link> </li>
<li><Link to='/list'>list</Link> </li>
</div>
<hr/>
<Switch>// 婚配到第一個婚配的路由就住手
<Route exact path="/" component={Home} /> //exact 示意途徑要準確完整婚配
<Route path="/about" component={About} /> //寫法1
<Route path="/list" render={() => <div>list</div>} /> //寫法2
<Redirect to="/"/> // 當都不婚配的時刻,實行這個
</Switch>
</div>
</Router>
);
}
}
const Home = () => {
return <div>home page</div>
}
const About = () => (
<div>
<h2>About</h2>
</div>
);
export default App;
-------------------------
//關於Router導入另有一種等價的運用體式格局,以下所示
import createHistory from 'history/createHashHistory'
<Router history={history}>
內里的內容同上
</Router>
申明 在react-router-dom內部包括許多組件,比方route,link,switch等等,更多組件請參考 這裏。上面只是一個簡樸的實例,完成簡樸的路由跳轉,關於申明都放在解釋里了。
路由理會
在上面的示例中,Router是轉發的關鍵,在這个中轉站有許多線路(Route),經由過程開關(Link)能夠啟動列車的運轉,乘坐列車就能夠發明新大陸(compontent) 。深切進去能夠發明Router只是供應了一個上下文環境, 細緻的路由功用的完成依託傳入的history屬性, 這個屬性的功用由history模塊供應,history模塊內里封裝了createBrowserHistory,createHashHistory,createMemoryHistory等等。由於一切模塊供應的功用接口一樣 所以我們以个中的createHashHistory模塊作為示例剖析下, 起首其供應的接口以下
const history = {
length: globalHistory.length, //歷史記錄數目 window.history.length
action: "POP", //操縱示意 能夠為REPLACE PUSH
location: initialLocation, //內部封裝的簡版window.location
createHref, //建立一個hash路由
push,
replace,
go, // window.history.go(n);
goBack, // go(-1);
goForward, //go(1);
block, // 地點變化,脫離當前頁時設置提醒信息
listen
};
return history;
下面選出幾個比較重要的細緻申明下
push
// const pushHashPath = path => (window.location.hash = path);
申明 摘出的重要邏輯增加瀏覽器hash地點
replace 替換瀏覽器hash地點
const hashIndex = window.location.href.indexOf("#");
window.location.replace(
window.location.href.slice(0, hashIndex >= 0 ? hashIndex : 0) + "#" + path
);
申明 摘出的重要邏輯替換瀏覽器hash地點
listen
const listen = listener => {
const unlisten = transitionManager.appendListener(listener);
checkDOMListeners(1);
return () => {
checkDOMListeners(-1);
unlisten();
};
};
申明 在transitionManager實例中保護了一個listener數組,appendListener增加一個Listener, checkDOMListeners是綁定事宜
window.addEventListener(HashChangeEvent, handleHashChange);
每當location地點轉變,HashChangeEvent觸發的時刻, 會掏出listeners然後實行,以下所示
transitionManager.notifyListeners(history.location, history.action);
block
const unblock = transitionManager.setPrompt(prompt);//註冊提醒信息
unblock() //實行后消除地點變化時提醒信息
總結
斷斷續續的終究把這篇文章寫好了,在此期間看了history源碼,寫了一些示例,盡可能將本身明白的東西以簡約直白的體式格局輸出出來,願望人人看后能產生共鳴。
參考源碼
history 4.7.2
react-router 4.3.0-rc.2
參考鏈接
http://reacttraining.cn/web/a…
https://juejin.im/post/5995a2…