本文是深入淺出 ahooks 原始碼系列文章的第一篇,該系列已整理成檔案-地址,覺得還不錯,給個 star 支持一下哈,Thanks,
第一篇主要介紹 ahooks 的背景以及整體架構,
React hooks utils 庫
自從 React 16.8 版本推出 React hooks,越來越多的專案使用 Function Component,React hooks utils 庫隨即誕生,它主要解決的兩個問題如下:
- 公共邏輯的抽象,
- 解決 React hooks 存在的弊端,比如閉包等,
那現在社區有哪些比較優秀的 React Hooks utils 庫呢?
react-use 是社區比較活躍的 React hooks utils 庫,它的 star 數達到了 29.6k,它的功能非常強大,擁有的 hooks 已經 100+,假如你需要功能比較齊全,可以考慮選擇 react-use,
如果不需要非常齊全的功能,只需要一些常見的功能,react-use 可能會稍微冗余了,可以考慮我們今天的主角——ahooks,目前它的 star 數為 10k(2022.08.10),也算是社區比較活躍,
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 一份,clone 下來,(當時我 folk 的時候還是用的 yarn,現在應該是用 pnpm,猜測是性能有關),
yarn run init
yarn start
如果你能成功跑起服務,就會看到和官方檔案一模一樣的頁面,
整體結構
從倉庫的根目錄的 package.json 中可以得到以下資訊,
- 檔案是使用
dumi,是一款為組件開發場景而生的檔案工具, - 該專案是一個
monoRepo,它的專案管理是通過 lerna 進行管理的, - 單元測驗是通過 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 工具庫
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/501588.html
標籤:其他
