大家好,我是若川。持續組織了近一年的源碼共讀活動,感興趣的可以?加我微信?ruochuan12?參與,每周大家一起學習200行左右的源碼,共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》?包含20余篇源碼文章。歷史面試系列。另外:目前建有江西|湖南|湖北
籍前端群,可加我微信進群。
本文是深入淺出 ahooks 源碼系列文章的第一篇,這個系列的目標主要有以下幾點:
加深對 React hooks 的理解。
學習如何抽象自定義 hooks。構建屬于自己的 React hooks 工具庫。
培養閱讀學習源碼的習慣,工具庫是一個對源碼閱讀不錯的選擇。
注:本系列對 ahooks 的源碼解析是基于 v3.3.13
。自己 folk 了一份源碼,主要是對源碼做了一些解讀,可見 詳情[1]。
第一篇主要介紹 ahooks 的背景以及整體架構。
React hooks utils 庫
自從 React 16.8 版本推出 React hooks,越來越多的項目使用 Function Component。React hooks utils 庫隨即誕生,它主要解決的兩個問題如下:
公共邏輯的抽象。
解決 React hooks 存在的弊端,比如閉包等。
那現在社區有哪些比較優秀的 React Hooks utils 庫呢?
react-use[2] 是社區比較活躍的 React hooks utils 庫,它的 star 數達到了 29.6k
。它的功能非常強大,擁有的 hooks 已經 100+。假如你需要功能比較齊全,可以考慮選擇 react-use。
如果不需要非常齊全的功能,只需要一些常見的功能,react-use 可能會稍微冗余了,可以考慮我們今天的主角——ahooks[3],目前它的 star 數為 9.2k
,也算是社區比較活躍。
ahooks
簡介
官方介紹如下:
ahooks,發音 [e? h?ks],是一套高質量可靠的 React Hooks 庫。在當前 React 項目研發過程中,一套好用的 React Hooks 庫是必不可少的,希望 ahooks 能成為您的選擇。
特點
它具有如下特點:
易學易用。
支持 SSR。
將訪問 DOM/BOM 的方法放在 useEffect 中(服務端不會執行),避免服務端執行時報錯。
源碼中可以看到很多
isBrowser
的判斷,主要是區分開瀏覽器環境和服務器環境。
對輸入輸出函數做了特殊處理,且避免閉包問題。
輸入的函數,永遠都是使用最新的一份。這個是通過
useRef
進行實現。輸出函數,地址都是不會變化的,這個是通過
useMemoizedFn
(ahooks 封裝的)實現的,其實現也是通過useRef
實現。后面我們會提到。
包含大量提煉自業務的高級 Hooks。
包含豐富的基礎 Hooks。
使用 TypeScript 構建,提供完整的類型定義文件。可以學習一些 TypeScript 的技巧。
hooks 種類
ahooks 基于 UI、SideEffect、LifeCycle、State、DOM 等分類提供了常用的 Hooks。如下所示:

ahooks 整體架構
項目啟動
我們先從 ahooks 中 folk 一份[4],clone 下來。
yarn?run?init
yarn?start
如果你能成功跑起服務,就會看到和官方文檔一模一樣的頁面。
整體結構
從倉庫的根目錄的 package.json 中可以得到以下信息。
文檔是使用
dumi
。是一款為組件開發場景而生的文檔工具。該項目是一個
monoRepo
。它的項目管理是通過 lerna[5] 進行管理的。單元測試是通過 jest 實現。
它的目錄結構中,可以看到 docs 中存放倉庫公共文檔。packages 中存放兩個包,hooks 和 use-url-state。整體的結構跟 dumi 中給出的 lerna 項目的結構相似。其中每個包下面的每個組件都可以書寫對應的文檔,不一樣的是,hooks 中每個組件多了 __tests__
文件夾,這個是用來寫單元測試的。

可以用以下一張圖,大致總結一下 ahooks 的工程架構:

hooks
剛剛也提到,ahooks 是采用了 monoRepo
的方式,我們的源碼都是在 packages 中,我們來看下 hooks。先看 packages/hooks/package.json
。另外要使用 useUrlState 這個 hook,需要獨立安裝 @ahooksjs/use-url-state
,其源碼在 packages/use-url-state
中。我理解官方的用意應該是這個庫依賴于 react-router,可能有一些項目不需要用到,把它提出來有助于減少包的大小。
npm?i?@ahooksjs/use-url-state?-S
回到 packages/hooks
。重點關注一下 dependencies 和 peerDependencies。可以看到其實它內部還是使用了一些其他的工具庫的,比如 lodash(估計是避免重復造輪子,但感覺這樣會導致包會變大)。后面我們也會對這些工具庫做一個探索。
"dependencies":?{"@types/js-cookie":?"^2.x.x","ahooks-v3-count":?"^1.0.0","dayjs":?"^1.9.1","intersection-observer":?"^0.12.0","js-cookie":?"^2.x.x","lodash":?"^4.17.21","resize-observer-polyfill":?"^1.5.1","screenfull":?"^5.0.0"
},
"peerDependencies":?{"react":?"^16.8.0?||?^17.0.0?||?^18.0.0"
},
另外解釋下 peerDependencies。
peerDependencies
的目的是提示宿主環境去安裝滿足插件peerDependencies
所指定依賴的包,然后在插件import
或者require
所依賴的包的時候,永遠都是引用宿主環境統一安裝的npm
包,最終解決插件與所依賴包不一致的問題。這里的宿主環境一般指的就是我們自己的項目本身了。
這對于封裝 npm 包非常重要。當你寫的包 a 里面依賴另一個包 b,而這個包 b 是引用這個包 a 的業務的常用的包的時候,建議寫在 peerDependencies
里,避免重復下載/多個版本共存。
總結
作為系列的第一篇,介紹了 React hooks utils 庫的背景以及 ahooks 的特點簡介和整體架構,接下來會探索各個常見的 hooks 方法實現,敬請期待。
參考
ahooks 正式發布:值得擁抱的 React Hooks 工具庫[6]
參考資料
[1]
詳情: https://github.com/GpingFeng/hooks
[2]react-use: https://github.com/streamich/react-use
[3]ahooks: https://ahooks.js.org/zh-CN/guide
[4]一份: https://github.com/GpingFeng/hooks
[5]lerna: https://www.lernajs.cn/
[6]ahooks 正式發布:值得擁抱的 React Hooks 工具庫: https://developer.aliyun.com/article/768059
我在阿里招前端,我該怎么幫你?(現在還可以加模擬面試群)
如何拿下阿里巴巴 P6 的前端 Offer
如何準備阿里P6/P7前端面試--項目經歷準備篇
大廠面試官常問的亮點,該如何做出?
如何從初級到專家(P4-P7)打破成長瓶頸和有效突破
若川知乎問答:2年前端經驗,做的項目沒什么技術含量,怎么辦?
如何準備20K+的大廠前端面試
·················?若川簡介?·················
你好,我是若川,畢業于江西高校。現在是一名前端開發“工程師”。寫有《學習源碼整體架構系列》20余篇,在知乎、掘金收獲超百萬閱讀。
從2014年起,每年都會寫一篇年度總結,已經堅持寫了8年,點擊查看年度總結。
同時,最近組織了源碼共讀活動,幫助4000+前端人學會看源碼。公眾號愿景:幫助5年內前端人走向前列。
掃碼加我微信 lxchuan12、拉你進源碼共讀群
今日話題
目前建有江西|湖南|湖北?籍 前端群,想進群的可以加我微信 lxchuan12?進群。分享、收藏、點贊、在看我的文章就是對我最大的支持~