我写了 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.mzph.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…

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.我有机会发…

我捡到宝了!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;您正在外面等出租车。 您将错过约会。 您等待几分钟&…

有哪些值得学习的大型 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…

如何在工作中打造影响力,带动同事?

大家好&#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.我的…

1万小时后,我从外包走进了字节跳动,现在出了一本书,文末送书!

谨以此书献给相信“努力有用”的你by 大史不说话《 前端跨界开发指南&#xff1a;JavaScript工具库原理解析与实战》先做个自我介绍我是大史不说话&#xff0c;是一名前端工程师&#xff0c;一个相信“努力有用”的、不太聪明的、行动力还可以的程序员。曾经因为一篇《10000小时…

视觉设计师跟平面设计_使设计具有视觉吸引力

视觉设计师跟平面设计Interaction Design is very gratifying.交互设计非常令人满意。 From fast critical thinking to extracting ideas in tangible forms within the team is sure fun and challenging.从快速的批判性思维到在团队内部以有形的形式提炼想法&#xff0c;无…

ExtJs4 笔记 Ext.tab.Panel 选项卡

本篇讲解选项卡控件。 一、基本选项卡 首先我们来定义一个基本的选项卡控件&#xff0c;其中每个Tab各有不同&#xff0c;Tab的正文内容可以有三种方式获取&#xff1a; 1.基本方式:通过定义html和items的方式。 2.读取其他html的信息:通过设置contentEl就可以获取其他html的信…

一直刷不动算法题,怀疑人生?试试五毒掌法!

大家好&#xff0c;我是若川。持续组织了近一年的源码共读活动&#xff0c;感兴趣的可以 加我微信 ruochuan12 参与&#xff0c;每周大家一起学习200行左右的源码&#xff0c;共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。历史面试系列。另外…

还在用开发者工具上传小程序? 快来试试 miniprogram-ci 提效摸鱼

1. 前言大家好&#xff0c;我是若川。持续组织了近一年的源码共读活动&#xff0c;感兴趣的可以 加我微信 ruochuan12 参与&#xff0c;每周大家一起学习200行左右的源码&#xff0c;共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含包含jQuery、underscore、lo…

超级玛丽马里奥版下载_将超级马里奥赋予生命

超级玛丽马里奥版下载Have you ever seen a zoetrope? If today’s sophisticated computer animation is the latest evolution of the form, then the remarkable zoetrope is a crucial ancestor; the transitional form between the drawing and the animation.等皆你见过…