情景描述
- 項(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
- 使用react-router改變路由
- 這些不同的改變路由的方式有什么區(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)的效果茴扁。簡而言之:頁面上所有的組件都會重新的掛載。
- 特點(diǎn):使用diff算法搭儒,將變化的組件進(jìn)行重新掛載穷当,沒有變化的組件只會調(diào)用其render方法提茁。最大限度的提高效率
-
使用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重新渲染