使用的合适的方式做路由跳转

情景描述

  • 项目中使用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
  • 这些不同的改变路由的方式有什么区别呢?
    • 原理
    • 结果

使用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会导致页面全部刷新,重新请求页面资源(或者重新从缓存中取出页面资源),视觉上会出现一个闪现的效果。简而言之:页面上所有的组件都会重新的挂载。
  • 使用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重新渲染

你可能感兴趣的:(使用的合适的方式做路由跳转)