日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

图解 React-router 源码

發布時間:2023/12/9 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 图解 React-router 源码 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

大家好,我是若川。歡迎加我微信 ruochuan12今天分享一篇react-router源碼文章,深入理解路由的本質。微信預計閱讀只需8分鐘。點擊下方卡片關注我,或者查看源碼系列文章。


閱讀源碼小 tips:從整體到細節,剛開始不要太拘泥于一行代碼的實現,先從整體去理解,理解好各自的關系,再去讀源碼。

首先,我們先不糾結于源碼細節。先用最簡單的話來概括一下 React-router 到底做了什么?

本質上, React-Router 就是在頁面 URL 發生變化的時候,通過我們寫的 path 去匹配,然后渲染對應的組件。

那么,從這句話,我們想一下如何分步驟實現:

  • 如何監聽 url 的變化 ?

  • 如何匹配 path,按什么規則 ?

  • 渲染對應的組件

  • 了解好需要實現的關鍵步驟,我們來將倉庫源碼下載下來。

    接下來我們看一下 GitHub, 它使用 lerna 管理同時管理多個包.也就是 Multirepo 概念。

    react-router 使用 lerna 來同時管理多個包. ( lerna ?的好處特別多,對于依賴關系大,同類型的包推薦使用 lerna 來統一管理。)

    核心庫是 react-router. react-router-dom 是在瀏覽器中使用的,react-router-native是在 rn 中使用的。

    如果不理解,直接看一下源碼就懂了。其實 react-router-dom 只是多了下面四個組件 BrowserRouter、 Link、NavLink、HashRouter, 其他其實都是直接引用 react-router 的。

    了解完多包的組織關系之后,我們回到前面如何實現 react-router 的 3個關鍵步驟,如下:

  • 如何監聽 url 的變化 ?

  • 如何匹配 path ?

  • 渲染對應的組件

  • 我們不自己來實現,直接看源碼,站在巨人的肩膀上來學習????。接下來我們來看一下 react-router-dom 官方文檔 的基本使用。

    export?default?function?App()?{return?(<BrowserRouter><div><Link?to="/">Home</Link><Link?to="/about">About</Link><Link?to="/topics">Topics</Link><Switch><Route?path="/about"><About?/></Route><Route?path="/"><Home?/></Route></Switch></div></BrowserRouter>); }

    從代碼中,我們可以觀察到下面幾點:

  • 最外層包裹了<BrowserRouter> ,它有什么意義?

  • 在 <Route />匹配的外層,包裹了<Switch>,作用是如果匹配了一個,則不會再繼續渲染另外一個。如何實現?

  • Route 中有 path 匹配路徑,包裹的則是渲染的組件。

  • 整體設計

    我們用一張圖來理解一下整個 react-router 是怎么實現的:

    接下來我們看看每一個步驟是怎么實現的。

    一、監聽 URL 的變化

    正常情況下,當 URL 發生變化時,瀏覽器會像服務端發送請求,但使用以下2種辦法不會向服務端發送請求:

    • 基于 hash

    • 基于 history

    react-router 使用了 history 這個核心庫。

    1. 選擇方式: ?history 或 hash

    HashRouter 先是從 history 中引用 createBrowserHistory ,然后將 history 和 children 傳入到 Router 。BrowseHistory同理。

    BrowseHistory 必須依賴服務器讓 url 都映射到 index.html ,否則會 404 。

    2. 監聽 URL 的變化,拿到對應的 history,location,match 等通過 Provider 注入到子組件中。

    二、Route 中匹配渲染組件

    這代碼可以分兩部分理解:

  • 是否匹配

  • 渲染組件

  • 1. 是否匹配

    computedMatch 是使用 Switch 包裹的子組件才有的值,Switch的作用是從上到下開始渲染,只要匹配到一個,其他的就不匹配。所以這里會先判斷 computedMatch 。

    匹配解析 path ,這里使用了第三方庫? path-to-regexp
    //?Make?sure?you?consistently?`decode`?segments. const?fn?=?match("/user/:id",?{?decode:?decodeURIComponent?});fn("/user/123");?//=>?{?path:?'/user/123',?index:?0,?params:?{?id:?'123'?}?} fn("/invalid");?//=>?false fn("/user/caf%C3%A9");?//=>?{?path:?'/user/caf%C3%A9',?index:?0,?params:?{?id:?'café'?}?}
    2. 組件渲染方式

    從文檔來看,它支持三種方式的渲染,如下:

    //?children?方式 <Route?exact?path="/"><HomePage?/> </Route>//?func?方式 <Routepath="/blog/:slug"render={({?match?})?=>?{//?Do?whatever?you?want?with?the?match...return?<div?/>;}} />//?component?方式 <Route?path="/user/:username"?component={User}?/>

    源碼部分如下:

    吐槽一下,作者怎么就不能好好用 if else 來寫,非要寫這么多變態的 ?:,請不要學習,除非你的項目只有你一個前端????。

    一下子看不懂也沒關系,我們來看下面的流程圖。

    從上面的代碼我們可以看出:

  • Router 渲染的優先級:children > ?component > render,三種方式互斥,只能使用一種。

  • 不匹配的情況下,只要 children 是函數,也會渲染

  • component 是使用 createComponent 來創建的, 這會導致不再更新現有組件,而是直接卸載再去掛載一個新的組件。如果是使用匿名函數來傳入 component ,每次 render 的時候,這個 props 都不同,會導致重新渲染掛載組件,導致性能特別差。因此,當使用匿名函數的渲染時,請使用 render 或 children 。

  • //?不要這么使用 <Route?path="/user/:username"?component={()?=>?<User/>?}?/>

    結論

  • 對于依賴關系大,同類型的包使用 lerna 來統一管理。盡量抽象出共用不可變的地方,比如 react-router 中的方法。

  • React-router 使用了Compound components(復合組件模式),在這種模式中,組件將被一起使用,它們可以方便的共享一種隱式的狀態,比如 Switch , 可以在這里通過 React.children 來控制包裹組件的渲染優先級,而無須使用者去控制。再比如我們經常使用的 <select />和 <option>, 可以通過 React.children 和 React.cloneElement 來劫持修改子組件,讓組件使用者通過更少的 api 來觸發更強大的功能。


  • 最近組建了一個江西人的前端交流群,如果你也是江西人可以加我微信 ruochuan12 拉你進群。



    ·················?若川出品?·················

    今日話題

    寫作其實是利他共贏的一種方式。長期輸出有價值的內容,會給自己帶來很多好處。所以交流群里常有人問如何高效學習前端,我有時會建議可以寫博客輸出。

    一個愿景是幫助5年內前端人走向前列的公眾號

    可加我個人微信 ruochuan12,長期交流學習

    推薦閱讀

    我在阿里招前端,我該怎么幫你?(現在還能加我進模擬面試群)

    如何拿下阿里巴巴 P6 的前端 Offer

    總結

    以上是生活随笔為你收集整理的图解 React-router 源码的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。