资讯专栏INFORMATION COLUMN

react-router 2.7.0源码深度分析

tianyu / 2213人阅读

摘要:介绍为提供路由管理为基于格式的系统提供了方便的切换页面功能。它在前端提供给了种方式通过或者浏览器原生的进行地址更新上一篇介绍了的方式本文则以的形式切入分析。代码剖析路由配置本生为组建内部组建如等。

前言

在前端单页面应用里面,路由是比较重要的部分,笔者的上一篇博文简单的路由介绍了简单的路由内部机制,本文则将分析react-router的内部机制。

介绍

react-router为react提供路由管理,为基于jsx格式的app系统提供了方便的切换页面功能。
它在前端提供给了2种方式,通过hashchange或者浏览器原生的history api进行地址更新,上一篇介绍了hash的方式,本文则以history api的形式切入分析。

代码剖析 路由配置

react-router本生为react组建,内部组建如Router,Route,IndexRoute, Redirect,Link等。
以下是摘自react-router example的路由配置


    
        
        
        
            
            
        
    


点此获取完整代码

对应结构图

在初始化过程中他会以children形式读入Router生命周期内,在被转化为数组,此时它内部的结构如下

路由初始化 初始化browserHistory对象

react-router依赖history^2.0模块生成的history对象,然后在Router生命周期componentWillMount中加入对应的封装如basename,query
useQueries.js 对history对象内的方法进行封装

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),不建议使用

初始化监听事件
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);
}

此时整体初始化完毕

改变路由
  /

以一次Link点击为例

触发Link组建的handleClick方法

调用router对象 push方法

拼装location对象

改变url栏的地址

调用updateLocation 触发changeListeners内的所有监听事件

回调函数内调用match方法,根据location对象正则匹配router对象,匹配出对应的组建 执行runLeaveHooks钩子

调用Router组建的setState(nextstate)

Router-context组建的render方法调用createElement

调用react.createElement

完成渲染

简洁的流转图

放上一个本人总结的一个简单流转过程图

详细流程图

对简洁的流程图熟悉之后,则可深入了解内部机制的细节如下图

归纳

虽然源码繁琐复杂,但是内部的核心仍是围绕着下面3块动作做一系列的封装.

注册监听事件:封装history对象的,生成router对象存储在Router内,并通过其注册监听事件,绑定相应的回调函数

触发监听事件:通过Link/browserHistory.push/浏览器回退快进/dom ready 等四种方式触发回调函数

回调函数: Router内的setState(next)最终触发react.createElement进而更新UI

最后

本文有什么不完善的地方,或者流程图有待改进的地方,敬请斧正。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/80293.html

相关文章

  • 前端路由实现与 react-router 源码分析

    摘要:回调函数将在更新时触发,回调中的起到了新的的作用。注册回调在中使用注册的回调函数,最终放在模块的回调函数数组中。 原文地址:https://github.com/joeyguo/blog/issues/2 在单页应用上,前端路由并不陌生。很多前端框架也会有独立开发或推荐配套使用的路由系统。那么,当我们在谈前端路由的时候,还可以谈些什么?本文将简要分析并实现一个的前端路由,并对 reac...

    ISherry 评论0 收藏0
  • react-router v5.x 源码分析和理解 SPA router 的原理

    摘要:一般情况下,都是作为等其他子路由的上层路由,使用了,接收一个属性,传递给消费子组件。创建对象,兼容老浏览器,其他和没有大区别总结分为四个包,分别为,其中是浏览器相关,是相关,是核心也是共同部分,是一些配置相关。 这篇文章主要讲的是分析 react-router 源码,版本是 v5.x,以及 SPA 路由实现的原理。 文章首发地址 单页面应用都用到了路由 router,目前来看实现路由有...

    Harriet666 评论0 收藏0
  • 从路由原理出发,深入阅读理解react-router 4.0源码

    摘要:通过前端路由可以实现单页应用本文首先从前端路由的原理出发,详细介绍了前端路由原理的变迁。接着从的源码出发,深入理解是如何实现前端路由的。执行上述的赋值后,页面的发生改变。   react-router等前端路由的原理大致相同,可以实现无刷新的条件下切换显示不同的页面。路由的本质就是页面的URL发生改变时,页面的显示结果可以根据URL的变化而变化,但是页面不会刷新。通过前端路由可以实现...

    Miyang 评论0 收藏0
  • 从路由原理出发,深入阅读理解react-router 4.0源码

    摘要:通过前端路由可以实现单页应用本文首先从前端路由的原理出发,详细介绍了前端路由原理的变迁。接着从的源码出发,深入理解是如何实现前端路由的。执行上述的赋值后,页面的发生改变。   react-router等前端路由的原理大致相同,可以实现无刷新的条件下切换显示不同的页面。路由的本质就是页面的URL发生改变时,页面的显示结果可以根据URL的变化而变化,但是页面不会刷新。通过前端路由可以实现...

    张红新 评论0 收藏0
  • 深入redux技术栈

    摘要:另外,内置的函数在经过一系列校验后,触发,之后被更改,之后依次调用监听,完成整个状态树的更新。总而言之,遵守这套规范并不是强制性的,但是项目一旦稍微复杂一些,这样做的好处就可以充分彰显出来。 这一篇是接上一篇react进阶漫谈的第二篇,这一篇主要分析redux的思想和应用,同样参考了网络上的大量资料,但代码同样都是自己尝试实践所得,在这里分享出来,仅供一起学习(上一篇地址:个人博客/s...

    imingyu 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<