在前端單頁面應用裏面,路由是比較重要的部分,筆者的上一篇博文簡單的路由介紹了簡單的路由內部機制,本文則將分析react-router的內部機制。前端
react-router爲react提供路由管理,爲基於jsx格式的app系統提供了方便的切換頁面功能。
它在前端提供給了2種方式,經過hashchange或者瀏覽器原生的history api進行地址更新,上一篇介紹了hash的方式,本文則以history api的形式切入分析。react
react-router本生爲react組建,內部組建如Router,Route,IndexRoute, Redirect,Link等。
如下是摘自react-router example的路由配置git
<Router history={withExampleBasename(browserHistory, __dirname)}> <Route path="/" component={App}> <IndexRoute component={Index}/> <Route path="/about" component={About}/> <Route path="users" component={Users}> <IndexRoute component={UsersIndex}/> <Route path=":id" component={User}/> </Route> </Route> </Router>
點此獲取完整代碼github
在初始化過程當中他會以children形式讀入Router生命週期內,在被轉化爲數組,此時它內部的結構以下
segmentfault
react-router依賴history^2.0模塊生成的history對象,而後在Router生命週期componentWillMount中加入對應的封裝如basename,query
useQueries.js 對history對象內的方法進行封裝api
function listen(listener) { return history.listen(function (location) { listener(addQuery(location)) }) } // Override all write methods with query-aware versions. function push(location) { history.push(appendQuery(location, location.query)) }
useBasename.js 對history對象內的方法進行封裝數組
function listen(listener) { return history.listen(function (location) { listener(addBasename(location)) }) } // Override all write methods with basename-aware versions. function push(location) { history.push(prependBasename(location)) }
Router.js 對history對象增長setRouteLeaveHook鉤子函數以及isActive函數瀏覽器
最終生成router對象 以this.router = router存在Router組建內部,this.history 已過期(issues),不建議使用react-router
this._unlisten = transitionManager.listen(function (error, state) { if (error) { _this.handleError(error); } else { _this.setState(state, _this.props.onUpdate); } }); function listen(listener) { changeListeners.push(listener); if (location) { listener(location); } else { var _location = getCurrentLocation(); allKeys = [_location.key]; updateLocation(_location); }
此時總體初始化完畢app
<Link to="about" activeStyle={ACTIVE}>/</Link>
以一次Link點擊爲例
放上一個本人總結的一個簡單流轉過程圖
對簡潔的流程圖熟悉以後,則可深刻了解內部機制的細節以下圖
雖然源碼繁瑣複雜,可是內部的核心還是圍繞着下面3塊動做作一系列的封裝.
本文有什麼不完善的地方,或者流程圖有待改進的地方,敬請斧正。