使用的合適的方式做路由跳轉(zhuǎn)

情景描述

  • 項(xiàng)目中使用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標(biāo)簽
      • a
    • 使用window對象的屬性:history和location
      • history.push
      • location.href
  • 這些不同的改變路由的方式有什么區(qū)別呢?
    • 原理
    • 結(jié)果

使用history 和 location (window屬性)做路由跳轉(zhuǎn)

history

  • 每個(gè)瀏覽器窗口,每個(gè)Tab,每個(gè)iframe都一個(gè)history對象
  • history記錄了從窗口打開開始的所有瀏覽歷史
  • 其中包含了go、back、forward等方法
特點(diǎn)
  • 雖然也可以改變路由,但是跳轉(zhuǎn)的新路由只可能實(shí)在history對象存儲過得路由
  • 不能通過直接給定新的url方式進(jìn)行跳轉(zhuǎn)
  • 使用history對象永遠(yuǎn)都不可能知道準(zhǔn)確的url

location

  • 提供了當(dāng)前窗口中加載的文檔的location相關(guān)信息,還提供了一些導(dǎo)航功能
    • 很多屬性不僅可以作為可讀信息,也可以被新的值覆蓋(因此可以做到查閱和設(shè)置)
  • 對象中有很多的方法可以實(shí)現(xiàn)路由的修改
    • location.assign(新的url) === window.loaction.href = 新的url (使用新的url完全的覆蓋舊的url,并且在history對象中生成一個(gè)新的url歷史)
    • location.replace(新的url) 和上面的方法作用一直但是特點(diǎn)是不會生成新的history而是直接覆蓋當(dāng)前的history

兩個(gè)對象在修改路由上的區(qū)別

  • history只能將路由改成曾經(jīng)訪問過得路由()
  • location可以導(dǎo)航到任何新的想去的路由
總結(jié): history對象只包含出棧的api甚至不能訪問棧中最后一條歷史記錄的詳情,location只能入棧或者replace瀏覽記錄和查看最后一條歷史記錄的詳情

缺點(diǎn)

  • 每次路由的跳轉(zhuǎn)都會導(dǎo)致頁面刷新(視覺上會出現(xiàn)閃現(xiàn)的效果)

使用react-router做路由跳轉(zhuǎn)

  • 使用link to做路由跳轉(zhuǎn)

    • 特點(diǎn):使用diff算法,將變化的組件進(jìn)行重新掛載,沒有變化的組件只會調(diào)用其render方法。最大限度的提高效率
      • 和標(biāo)簽a的區(qū)別在于:a會導(dǎo)致頁面全部刷新,重新請求頁面資源(或者重新從緩存中取出頁面資源),視覺上會出現(xiàn)一個(gè)閃現(xiàn)的效果。簡而言之:頁面上所有的組件都會重新的掛載。
  • 使用browserHistory.push做路由跳轉(zhuǎn)

    • 原理和linkto完全一致,都是用diff算法做跳轉(zhuǎn)
  • 使用this.props.router.push
    • 原理和linkto完全一致,都是用diff算法做跳轉(zhuǎn)
    • 補(bǔ)充:
      • 1.使用react-router相當(dāng)于每一個(gè)Route都是一個(gè)組件,而對應(yīng)的component都是這個(gè)Router的子組件
      • 2.因此Route作為父組件會給子組件傳遞很多的數(shù)據(jù)
        • location對象
        • params對象
        • children
        • route:當(dāng)前路由的路徑和組件內(nèi)容
        • router:其中包含很多瀏覽器的方法

總結(jié)上面三個(gè)方式原理和結(jié)果都一致,唯一區(qū)別

  • linkto:在組件級別進(jìn)行跳轉(zhuǎn)
  • browserHistory模仿瀏覽器的history對象的行為,但是api來自于react-router
  • this.props.router.push:api來自父Route類

特點(diǎn)

  • 路由的跳轉(zhuǎn)不會導(dǎo)致閃現(xiàn),使用diff算法對于新路由中還會存在的組件只調(diào)用組件的render方法,對于新路由中不會存在的組件會銷毀然后重新掛載新路由中的組件

解惑項(xiàng)目中使用react-router

  • Q1:項(xiàng)目中使用browserhistory進(jìn)行路由跳轉(zhuǎn),沒有閃現(xiàn)。

  • A1:因?yàn)樽钔鈱咏M件中是App,其中包含了Header和Footer,內(nèi)容是this.props.children,因此不論路由怎樣修改,這個(gè)App都在,每次之后調(diào)用App的render方法不會將其銷毀

  • Q2:每次使用browserHistory.push會調(diào)用組件的那些生命周期方法呢?

  • A2:關(guān)系到路由跳轉(zhuǎn)的組件會被分成三種

    • 在新老路由中的都會存在的組件(比如App):render被調(diào)用
    • 只在老路由中存在的組件:ComponentWillUnmount會被調(diào)用,也就說會被銷毀
    • 只在新路由中存在的組件:會被重新掛載(執(zhí)行一套掛載的方法)
  • Q3:為什么選擇使用react-router作為react路由控制的庫呢?

  • A3:原理和React相似,react是屬性改變引起組件的render ui重新渲染。而react-router中l(wèi)ocation的改變引起Route組件的render然后ui重新渲染

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容