我寫了 ahooks 源碼分析系列,收到官方邀請我一起維護,這是一次提 PR 的記錄...

大家好,我是若川。持續組織了近一年的源碼共讀活動,感興趣的可以?加我微信?ruochuan12?參與,每周大家一起學習200行左右的源碼,共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》?包含20余篇源碼文章。歷史面試系列。另外:目前建有江西|湖南|湖北籍前端群,可加我微信進群。

本文是深入淺出 ahooks 源碼系列文章的第八篇,這個系列的目標主要有以下幾點:

  • 加深對 React hooks 的理解。

  • 學習如何抽象自定義 hooks。構建屬于自己的 React hooks 工具庫。

  • 培養閱讀學習源碼的習慣,工具庫是一個對源碼閱讀不錯的選擇。

注:本系列對 ahooks 的源碼解析是基于 v3.3.13。自己 folk 了一份源碼,主要是對源碼做了一些解讀,可見 詳情[1]

本篇文章算是該系列的一個彩蛋篇,記錄一下第一次給開源項目提 PR 的過程(之前好像也有過,不過那個非常小的一個改動),希望能夠幫助更多的人參與到開源項目中來。

起因

在寫了幾篇關于 ahooks 的文章之后,收到了官方同學的私信。

0714a9ced8d481614fbff93e42b6408d.png

這讓我受寵若驚的同時也有點小興奮和惶恐。

興奮是,之前感覺參與開源是一件遙不可及的事情,現在似乎我也能夠去做了。當然也有私心,假如我的簡歷上有給開源項目做貢獻的經歷,那豈不是一個不錯的加分項?

惶恐的是,我之前沒有參與過開源項目,擔心自己不能做好這件事。

根據大佬的建議,我決定先從一些 issue 入手,也就是幫忙解決一下 issue。

明確問題OR需求

于是我抱著試試看的態度,看了一下官方的 issue,看到這么一條。issue 詳情[2]

c4341ed94e3789271cb6a8d4aef5da2a.png

剛好我之前對 useRequest 源碼做過一些分析——如何使用插件化機制優雅的封裝你的請求[3]。于是我決定 fix 一下這個 issue。

這個 issue 的需求很簡單,就是希望輪詢失敗后,能夠支持最大的輪詢次數,假如失敗的次數大于這個值,則停止輪詢。

編碼前準備

首先,從 ahooks 官方 GitHub 中 folk 一份。這個操作我之前已經做了。

b6700db09ec59f59d49fc0aa04e786a7.png

第二步,基于 master 切換一個功能分支。如下:

git?checkout?-b?fix/pollingSupportRetryCount

最后就是環境的一些初始化操作,不同的倉庫不同,ahooks 如下:

yarn?run?init
yarn?start

功能實現

我們先來看下現在 useRequest 的輪詢的實現,其原理主要是在一個請求結束的時候(不管成功與失敗),通過 setTimeout 進行重新請求,達到輪詢的效果。

onFinally:?()?=>?{//?省略部分代碼...//?通過?setTimeout?進行輪詢timerRef.current?=?setTimeout(()?=>?{fetchInstance.refresh();},?pollingInterval);
},

我的想法是,定義一個 options 參數,pollingErrorRetryCount,默認為 -1,代表沒有限制。

另外定義一個變量,記錄當前重試的次數:

const?countRef?=?useRef<number>(0);

當開發者設置了 pollingErrorRetryCount,并且重試的數量大于該值,我們就直接返回,不執行輪詢的邏輯。

當成功或者失敗的時候,更新當前重試的次數:

onError:?()?=>?{countRef.current?+=?1;
},
onSuccess:?()?=>?{countRef.current?=?0;
},

然后在請求結束的時候,判斷重試的次數有沒有達到了開發設置的次數,假如沒有則執行重試操作。有則重置重試的次數,停止輪詢。

onFinally:?()?=>?{if?(pollingErrorRetryCount?===?-1?||//?When?an?error?occurs,?the?request?is?not?repeated?after?pollingErrorRetryCount?retries(pollingErrorRetryCount?!==?-1?&&?countRef.current?<=?pollingErrorRetryCount))?{//?忽略部分代碼timerRef.current?=?setTimeout(()?=>?{fetchInstance.refresh();},?pollingInterval);}?else?{countRef.current?=?0;}
},

測試用例

上述整體的改造并不困難,但是我在寫測試用例的時候,就開始踩坑了,因為我很少書寫前端的測試用例,還是針對于 hooks 的測試用例。這里是我耗時最多的地方。

最終用例如下:

//?省略部分代碼...
//?if?request?error?and?set?pollingErrorRetryCount
//?and?the?number?of?consecutive?failures?exceeds?pollingErrorRetryCount,?polling?stops
let?hook2;
let?errorCallback;
act(()?=>?{errorCallback?=?jest.fn();hook2?=?setUp(()?=>?request(0),?{pollingErrorRetryCount:?3,pollingInterval:?100,pollingWhenHidden:?true,onError:?errorCallback,});
});expect(hook2.result.current.loading).toEqual(true);
expect(errorCallback).toHaveBeenCalledTimes(0);act(()?=>?{jest.runAllTimers();
});
await?hook2.waitForNextUpdate();
expect(hook2.result.current.loading).toEqual(false);
expect(errorCallback).toHaveBeenCalledTimes(1);act(()?=>?{jest.runAllTimers();
});
await?hook2.waitForNextUpdate();
expect(errorCallback).toHaveBeenCalledTimes(2);act(()?=>?{jest.runAllTimers();
});
await?hook2.waitForNextUpdate();
expect(errorCallback).toHaveBeenCalledTimes(3);act(()?=>?{jest.runAllTimers();
});
await?hook2.waitForNextUpdate();
expect(errorCallback).toHaveBeenCalledTimes(4);act(()?=>?{jest.runAllTimers();
});
expect(errorCallback).toHaveBeenCalledTimes(4);act(()?=>?{hook2.result.current.run();
});
act(()?=>?{jest.runAllTimers();
});
await?hook2.waitForNextUpdate();
expect(errorCallback).toHaveBeenCalledTimes(5);hook2.unmount();
//?省略部分代碼...

大致解釋下該測試用例的邏輯,我設置了重試三次,錯誤之后,運行了三次,errorCallback 就會被調用了 4 次(包括錯誤那次)。在第五次執行的時候,就不會執行 errorCallback,也就還是 4 次。然后我們手動 run 一次請求,期待 errorCallback 應該執行 5 次。

這里踩了一個坑,就是第五次請求的時候,我之前是會寫一個等待定時器執行的操作,但實際上這里它是不會執行定時器的,導致一直報錯,在這里折騰了很久。后來刪除了下面的代碼才執行成功。

act(()?=>?{jest.runAllTimers();
});
-?await?hook2.waitForNextUpdate();
expect(errorCallback).toHaveBeenCalledTimes(4);

文檔以及 Demo 補充

畢竟加了一個新的 API 參數,需要在文檔中注明,而且中英文文檔都需要補充,還加上了一個 Demo 示例。

e1f6869c6b5b8ec68006bff0b82f2885.png883e3f26a4c4fd0cef0559e0142eb78d.png

提 PR

上述都完成之后,就可以提交你的代碼了,提交完,去到在你 folk 過來的項目中,可以看到這個。

6b0a595fb0689e0b93ee5b3c93604327.png

我們需要點擊圖中框起來的「Compare & pull request 」,之后就會出現如下圖

2b47a34ea37000d3a3d4038e0c8f0b20.png
圖來自網絡,演示用

默認會幫我們選好分支的,我們只需要完善其中的信息,還有我們之前提交的 message 也可以修改。最好可以用英文來解釋,本次提交的內容。

最后點擊提交之后就好了。

還有一個提 PR 的入口,如下所示:

8726ce8009836eddab0d205299918374.png

最后等待官方 CR 就可以了(上面的實現其實部分是 CR 后改的)。目前該 PR 已經被合入到 master。

總結思考

給開源項目提 PR 操作過程不是一件很復雜的事情,重點在于需求的修改。往往需要考慮到多種邊界場景,這個時候,我們就需要前端的單元測試來幫助我們覆蓋全面的場景。

另外,對于一些還沒有參與開源項目經驗的同學來講,我覺得類似 ahooks 這種工具庫是一個不錯的選擇:

  • 它的模塊劃分更加清晰,你改了一個模塊的功能,影響面可以更好的預估。對新人比較友好。

  • 邏輯相對簡單,其實你會發現很多代碼說不定在你們的業務項目中的 utils/hooks 文件夾中就有。

  • 社區比較活躍,維護者能夠較快的響應。

希望對大家有所幫助。

系列文章:

  • 大家都能看得懂的源碼(一)ahooks 整體架構篇[4]

  • 如何使用插件化機制優雅的封裝你的請求hook [5]

  • ahooks 是怎么解決 React 的閉包問題的?[6]

  • ahooks 是怎么解決用戶多次提交問題?[7]

  • ahooks 中那些控制“時機”的hook都是怎么實現的?[8]

  • 如何讓 useEffect 支持 async...await?[9]

  • 如何讓定時器在頁面最小化的時候不執行?[10]

參考資料

[1]

詳情: https://github.com/GpingFeng/hooks

[2]

issue 詳情: https://github.com/alibaba/hooks/issues/1645

[3]

如何使用插件化機制優雅的封裝你的請求: https://juejin.cn/post/7105733829972721677

[4]

大家都能看得懂的源碼(一)ahooks 整體架構篇: https://juejin.cn/post/7105396478268407815

[5]

如何使用插件化機制優雅的封裝你的請求hook : https://juejin.cn/post/7105733829972721677

[6]

ahooks 是怎么解決 React 的閉包問題的?: https://juejin.cn/post/7106061970184339464

[7]

ahooks 是怎么解決用戶多次提交問題?: https://juejin.cn/post/7106461530232717326

[8]

ahooks 中那些控制“時機”的hook都是怎么實現的?: https://juejin.cn/post/7107189225509879838

[9]

如何讓 useEffect 支持 async...await?: https://juejin.cn/post/7108675095958126629

[10]

如何讓定時器在頁面最小化的時候不執行?: https://juejin.cn/post/7109399243202232357


我在阿里招前端,我該怎么幫你?(現在還可以加模擬面試群)
如何拿下阿里巴巴 P6 的前端 Offer
如何準備阿里P6/P7前端面試--項目經歷準備篇
大廠面試官常問的亮點,該如何做出?
如何從初級到專家(P4-P7)打破成長瓶頸和有效突破
若川知乎問答:2年前端經驗,做的項目沒什么技術含量,怎么辦?

如何準備20K+的大廠前端面試

e734de00631179c67a23657f5a3b7b62.gif

·················?若川簡介?·················

你好,我是若川,畢業于江西高校。現在是一名前端開發“工程師”。寫有《學習源碼整體架構系列》20余篇,在知乎、掘金收獲超百萬閱讀。
從2014年起,每年都會寫一篇年度總結,已經堅持寫了8年,點擊查看年度總結。
同時,最近組織了源碼共讀活動,幫助4000+前端人學會看源碼。公眾號愿景:幫助5年內前端人走向前列。

7c6f6461125b88ace59ad7ff8270e33f.jpeg

掃碼加我微信 lxchuan12、拉你進源碼共讀

今日話題

目前建有江西|湖南|湖北?籍 前端群,想進群的可以加我微信 lxchuan12?進群。分享、收藏、點贊、在看我的文章就是對我最大的支持~

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/274582.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/274582.shtml
英文地址,請注明出處:http://en.pswp.cn/news/274582.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Hdu 4415 Assassin's Creed 【貪心】.cpp

題意&#xff1a; 某A有一個劍 堅韌度為m 他可以用這個劍去攻打別的隊伍 殺掉第 i 個隊伍需要消耗的堅韌度為 Ai 并可以用得到的劍去打別的隊(Bi個) 但是打完別的隊這個劍就不能用了 問怎么用最少的堅韌度擊敗最多的隊伍 給出T組樣例 每個樣例給出n m n表示有n個隊 接下來n行給…

ahooks 整體架構篇,大家都能看得懂

大家好&#xff0c;我是若川。持續組織了近一年的源碼共讀活動&#xff0c;感興趣的可以 加我微信 ruochuan12 參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。歷史面試系列。另外…

gif動態圖gif出處_我喜歡GIF的怪異事物

gif動態圖gif出處I was recently reminded that I never wrote down all the weird things I learned about the GIF file format when implementing GIF decoding/playback at work last year. (I was reminded of this because I wrote a line in a corporate blog post draf…

C#字符串學習筆記

前言&#xff1a;記得我們老師說過一句話&#xff0c;對字符串的學習程度就是當別人打你一拳你知道痛的情況&#xff0c;所以字符串的處理我們必須學的差不多&#xff0c;這幾篇博客完全是我的學習過程中記錄的筆記&#xff0c;在這里分享一下讓很多剛開始學習.net編程的人能夠…

Git基礎教程(必學)

大家好&#xff0c;我是若川。持續組織了近一年的源碼共讀活動&#xff0c;感興趣的可以 加我微信 ruochuan12 參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。歷史面試系列。另外…

用戶體驗改善案例_優化用戶體驗案例研究的五種方法

用戶體驗改善案例重點 (Top highlight)I’ve had the opportunity to give several portfolio reviews, and I want to share some common themes I see and how you can improve them to put your best foot forward as you search for that new product design gig.我有機會發…

video from html5

掌握HTML5中的多媒體--視頻(video) 除非你一直生活在一個偏遠的島嶼上,過去一年左右的時間,你應該已經聽說過HTML5的各式炒作。HTML5將重塑富Web應用的未來。 下面 Figure 1的示例展示了HTML5中video標簽與傳統的object標簽的不同. Figure 1 1. <section> 2. <h…

我撿到寶了!2022版前端面試上岸手冊,最新最細致!

大裁員背景下&#xff0c;沒什么比辭職后找不到工作更扎心&#xff01;在行情好轉前&#xff0c;前端程序員只能“猥瑣發育”&#xff0c;不輕易跳槽&#xff0c;同時要修煉內功&#xff1a;對八股文、底層源碼、重點項目等進行查缺補漏&#xff0c;靜待行情好轉抓住機會&#…

flo file_Flo菜單簡介:可擴展的拇指友好型移動導航

flo fileWhen it comes to using my phone, I’m a thumb guy and I like using my phone held in one hand. Well, apparently 49% of us prefer it like this.說到使用手機&#xff0c;我是個拇指小伙&#xff0c;我喜歡用一只手握住手機。 好吧&#xff0c;顯然我們當中有49…

超炫的iphone應用UI/UX設計賞析

日期&#xff1a;2012-10-5 來源&#xff1a;GBin1.com 要想成為一款成功的iOS應用&#xff0c;不單單是功能設計&#xff0c;還需要有超棒的用戶界面和用戶體驗的完美設計。為了帶給大家更多的設計靈感&#xff0c;今天我們分享另外一套來自dribbble的iOS應用UI和UX設計&…

Git實戰進階教程

大家好&#xff0c;我是若川。持續組織了近一年的源碼共讀活動&#xff0c;感興趣的可以 加我微信 ruochuan12 參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。歷史面試系列。另外…

什么是設計模式_什么是設計?

什么是設計模式Imagine, you are out waiting for a taxi. You are about to miss your appointment. You wait for minutes but Good Lord! — there’s not a single taxi that can offer you a ride.想象一下&#xff0c;您正在外面等出租車。 您將錯過約會。 您等待幾分鐘&…

hive實現not in

當前HIVE 不支持 not in 中包含查詢子句的語法&#xff0c;形如如下的HQ語句是不被支持的: 查詢在key字段在a表中&#xff0c;但不在b表中的數據 select a.key from a where key not in(select key from b) 該語句在hive中不支持 可以通過left outer join進行查詢,&#xff0…

有哪些值得學習的大型 React 開源項目?

大家好&#xff0c;我是若川。持續組織了近一年的源碼共讀活動&#xff0c;感興趣的可以 加我微信 ruochuan12 參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。歷史面試系列。另外…

成年人的樣子是什么樣子_不只是看樣子

成年人的樣子是什么樣子As a branding, packaging, and digital product designer, both at Input Logic and as a freelancer, I work with clients across a wide array of industries, and am responsible for simultaneously getting to the heart of what each client wan…

HDU 3664 Permutation Counting(DP)

題目鏈接 弱爆啦&#xff0c;組合弱爆了&#xff0c;反正是沒想出來怎么搞這個題&#xff0c;其實這個公式不難推啊&#xff0c;反正就是沒推出來。今天隊內賽&#xff0c;實在是沒辦法了&#xff0c;暴力寫了個DFS&#xff0c;先把10以內的打出表來&#xff0c;發現類似楊輝三…

如何在工作中打造影響力,帶動同事?

大家好&#xff0c;我是若川。持續組織了近一年的源碼共讀活動&#xff0c;感興趣的可以 加我微信 ruochuan12 參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。歷史面試系列。另外…

谷歌maps菜單語言設置_Google Maps:拯救未來之路— UX案例研究

谷歌maps菜單語言設置I have a lousy sense of direction, so Google Maps has always been my right-hand app. On a whim last year, I decided to skip the beach and sunburn and head to Budapest for spring break. That’s when Google Maps became my best friend.我的…

this和prototype

this出現在構造函數中&#xff0c;更多的是表示一種特有的屬性&#xff1b; prototype主要用于拓展函數的屬性&#xff0c;方法。 在函數類實例化的時候&#xff0c;this的屬性需要復制相應的副本&#xff0c;prototype不用。 function Blog(title,content) { this.titletitle;…

1萬小時后,我從外包走進了字節跳動,現在出了一本書,文末送書!

謹以此書獻給相信“努力有用”的你by 大史不說話《 前端跨界開發指南&#xff1a;JavaScript工具庫原理解析與實戰》先做個自我介紹我是大史不說話&#xff0c;是一名前端工程師&#xff0c;一個相信“努力有用”的、不太聰明的、行動力還可以的程序員。曾經因為一篇《10000小時…