情景描述
- 项目中使用react-router和react-router-redux这两种第三方的路由库
- 其中包含了很多可以改变路由的方式方式:browserHistory.push、link to()、a、window.location.href、react-router-redux中的push方法
- 使用react-router改变路由
- link to
- browserhistory.push
- 使用react-router-redux改变路由
- push方法(react-router-redux)
- 使用html标签
- a
- 使用window对象的属性:history和location
- history.push
- location.href
- 使用react-router改变路由
- 这些不同的改变路由的方式有什么区别呢?
- 原理
- 结果
使用history 和 location (window属性)做路由跳转
history
- 每个浏览器窗口,每个Tab,每个iframe都一个history对象
- history记录了从窗口打开开始的所有浏览历史
- 其中包含了go、back、forward等方法
特点
- 虽然也可以改变路由,但是跳转的新路由只可能实在history对象存储过得路由
- 不能通过直接给定新的url方式进行跳转
- 使用history对象永远都不可能知道准确的url
location
- 提供了当前窗口中加载的文档的location相关信息,还提供了一些导航功能
- 很多属性不仅可以作为可读信息,也可以被新的值覆盖(因此可以做到查阅和设置)
- 对象中有很多的方法可以实现路由的修改
- location.assign(新的url) === window.loaction.href = 新的url (使用新的url完全的覆盖旧的url,并且在history对象中生成一个新的url历史)
- location.replace(新的url) 和上面的方法作用一直但是特点是不会生成新的history而是直接覆盖当前的history
两个对象在修改路由上的区别
- history只能将路由改成曾经访问过得路由()
- location可以导航到任何新的想去的路由
总结: history对象只包含出栈的api甚至不能访问栈中最后一条历史记录的详情,location只能入栈或者replace浏览记录和查看最后一条历史记录的详情
缺点
- 每次路由的跳转都会导致页面刷新(视觉上会出现闪现的效果)
使用react-router做路由跳转
-
使用link to做路由跳转
- 特点:使用diff算法,将变化的组件进行重新挂载,没有变化的组件只会调用其render方法。最大限度的提高效率
- 和标签a的区别在于:a会导致页面全部刷新,重新请求页面资源(或者重新从缓存中取出页面资源),视觉上会出现一个闪现的效果。简而言之:页面上所有的组件都会重新的挂载。
- 特点:使用diff算法,将变化的组件进行重新挂载,没有变化的组件只会调用其render方法。最大限度的提高效率
-
使用browserHistory.push做路由跳转
- 原理和linkto完全一致,都是用diff算法做跳转
- 使用this.props.router.push
- 原理和linkto完全一致,都是用diff算法做跳转
- 补充:
- 1.使用react-router相当于每一个Route都是一个组件,而对应的component都是这个Router的子组件
- 2.因此Route作为父组件会给子组件传递很多的数据
- location对象
- params对象
- children
- route:当前路由的路径和组件内容
- router:其中包含很多浏览器的方法
总结上面三个方式原理和结果都一致,唯一区别
- linkto:在组件级别进行跳转
- browserHistory模仿浏览器的history对象的行为,但是api来自于react-router
- this.props.router.push:api来自父Route类
特点
- 路由的跳转不会导致闪现,使用diff算法对于新路由中还会存在的组件只调用组件的render方法,对于新路由中不会存在的组件会销毁然后重新挂载新路由中的组件
解惑项目中使用react-router
-
Q1:项目中使用browserhistory进行路由跳转,没有闪现。
-
A1:因为最外层组件中是App,其中包含了Header和Footer,内容是this.props.children,因此不论路由怎样修改,这个App都在,每次之后调用App的render方法不会将其销毁
-
Q2:每次使用browserHistory.push会调用组件的那些生命周期方法呢?
-
A2:关系到路由跳转的组件会被分成三种
- 在新老路由中的都会存在的组件(比如App):render被调用
- 只在老路由中存在的组件:ComponentWillUnmount会被调用,也就说会被销毁
- 只在新路由中存在的组件:会被重新挂载(执行一套挂载的方法)
-
Q3:为什么选择使用react-router作为react路由控制的库呢?
-
A3:原理和React相似,react是属性改变引起组件的render ui重新渲染。而react-router中location的改变引起Route组件的render然后ui重新渲染
网友评论