• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

第三期ahooks全-Part1

武飞扬头像
海海前端
帮助3

hello,我是海海

从这一期我们将开启一个新的旅程——ahooks。阅读时间10分钟。

由于ahooks内容比较多,我将拆分成几个章节,本期我们先从整体的角度认识ahooks,并讲解比较简单的“开发”hooks和“生命周期”hooks。

不同于其他介绍ahooks的文章,本系列会对每一个hook从what(是什么)、how(怎么用)、why(实现原理)、when(啥时候用)做全方面的讲解。

欢迎转载,请注明原文和作者

有任何不对的地方,欢迎底部发消息给我。

本期大纲:

  • ahooks:react hooks的扩展

  • 别急,让我们整体认识ahooks

  • 从dev-hooks开始

    • useTrackedEffect(GPS定位装置)
    • useWhyDidYouUpdate(我徒弟呢?我不到啊!)
  • 别忘了,还有lifecycle-hooks

    • useMount(挂载之后)
    • useUnmount(卸载之前)
    • useUnmountedRef(查询是否卸载)

学新通

有点懵圈,让我们开始吧!

ahooks:hooks的扩展

2018年,React v16.8版本发布,hooks作为引入的一个新特性,允许开发者在不使用class的情况下使用state和其他React特性。这些hooks似乎足够我们使用,就像乐高的积木,这些都是最基础的功能。等到了复杂的业务场景,我们就需要组合、复用这些hooks

2019年8月,阿里发布了ahooks库v0.1.0。当时只有包含useAPI(现在是useRequest)等5个hooks。

2019年9月,在仅过了一个月之后,v1版本正式发布。hooks数量增加到了8个。

2020年6月,v2版本发布,hooks数量快速增长,到达了31个。其中一个重大的修改,是使用userRequest替换了6个hooks。

2021年12月,v3版本发布。

2022年3月,React v18版本发布。至此,React hooks已有长足的发展。我们在前几期的文章中粗略的描述了这些hooks的功能。

截止到2023年7月,ahooks已经包括了以下不同类别的76个hooks:

  • 强大的useRequest
  • DOM(DOM操作)
  • Scene(业务)
  • State(状态)
  • Effect(副作用)
  • Dev(开发模式)
  • Advanced(高级)
  • LifeCycle(组件生命周期)

学新通

从dev-hooks开始

Dev 类别下只有2个hooks,比较简单。我们从这里开始我们的旅程。

【v2.9.0添加】

useTrackedEffect(GPS定位装置)

  • what:当useEffect变化时,追踪是哪个依赖触发的
  • how:用法与useeffect相同,回调函数添加触发依赖的参数
  • when:debug-useEffect
  • why:如下图1-1和图1-2所示

学新通

图1-1:useTrackedEffect关键代码

学新通

图2-2:useTrackedEffect核心原理

useTrackedEffect关键代码如图1-1所示,这里忽略了typescript类型和diffTwoDeps算法函数。

算法流程和原理可以参考图1-2。

通过map方法遍历和Object.is方法比较新旧的依赖项,输出对应的产生改变的依赖的索引下标。

这里有必要对Object.is进行下讲解,都说Object.is是浅比较的意思,那么什么是浅比较?

浅比较关注比较对象的引用是否相同,深比较关注的是值是否相同。所以,对这个useTrackedEffect来说,只要依赖的引用不变,就不会触发回调函数,这一点和useEffect相同。

看到这里的时候,我产生了我上我也行的幻觉!

【v2.2.0添加】

useWhyDidYouUpdate(我徒弟呢?我不到啊!)

  • what:追踪哪一个状态、属性触发组件rerender(重渲染)
  • how:自定义字符串表示debug的组件名字;一个需要追踪的属性或者状态对象;
  • when:debug组件渲染
  • why:如下图1-3和图1-4所示

学新通

图1-3:useWhyDidYouUpdate关键代码

学新通

图1-4:useWhyDidYouUpdate基本原理

这个hooks设计的绝妙之处就在于利用了useEffect在没有依赖数组时会每次执行!

同时在这里,我们又看到了useRef用来存储上一次的值。

学新通

我徒弟呢?

当你的组件找不到"徒弟"时,可以试试useWhyDidYouUpdate

学新通

别忘了,还有lifecycle-hooks

虽然我们有了hooks可以免于编写类组件的痛苦,但是有时候我们又想利用类组件的生命周期做些事情。

我们可以利用下面的生命周期hooks。

【v1.8.0添加】

useMount(挂载之后)

  • what:和componentDidMount`用法相同

  • how:无参回调函数

  • when

    • 添加事件监听、订阅事件
    • 添加定时器
    • 发送请求,初始化组件数据
    • 获取元素的尺寸和位置
  • why:如下图1-5和图1-6所示

学新通

图1-5:useMount关键代码

学新通

图1-6:useMount基本实现

可以看到useMount只是对useEffect做了一层包装。

此外,useMount还对参数做了typeof判断是否为函数,但是我感觉是多余的,为什么不直接用useEffect去处理!知道的同学可以在评论区留言给我。

【v1.7.0添加】

useUnmount(卸载之前)

  • what:和componentWillUnMount用法相同

  • how:无参回调函数

  • when:

    • 移除事件监听、取消订阅事件
    • 清除定时器
    • 中断/取消异步操作
  • why:如下图1-7和图1-8所示

学新通

图1-7:useUnmount关键代码

学新通

图1-8:useUnmount核心逻辑

这个hook的原理也很简单,和useMount异曲同工,都是利用了useEffect的特性,只不过这里使用了useEffect的回调函数返回值。

到这里,我们其实明白了,lifecycle这一部分的本质是对useEffect做了拆解,说明充分了解useEffect的原理和使用对我们了解ahooks是有帮助的。

【v2.10.8添加】

useUnmountedRef(查询某组件是否卸载了)

  • what:查询组件的状态(卸载/没卸载)
  • how:在要查询的组件中使用该hook,通过获取xx.current(xx是hook的返回值)的布尔值,得到组件是否被卸载。具体使用见下方代码。
  • when:异步函数在获取到结果后,可能需要判断组件是否被卸载(我很少碰到这种情况,又碰到的同学可以在评论区留言)
  • why:如下图1-9和图1-10所示
const MyComponent = () => {
  const unmountedRef = useUnmountedRef();
  useEffect(() => {
    setTimeout(() => {
      // 如果组件已经被卸载,则此部分代码无法访问被卸载的组件。
      // 但是可以通过useUnmountedRef返回的闭包,获取到组件的信息
      // hook本质:一个闭包
      if (!unmountedRef.current) {
        message.info('component is alive');
      }
    }, 3000);
  }, []);

  return <p>Hello World!</p>;
};

学新通

图1-9:useUnmountedRef关键代码

学新通

图1-10:useUnmountedRef算法核心

可以看到,这个实现的原理其实非常简单。无非是在组件中利用了useEffect返回值和useRef引用不变的特性。但是加在一起就变成了有用的东西。

好了,今天的旅程到这里就结束了,谢谢你的陪伴!


感谢你的耐心阅读,如果觉得好的话,可以给我点个赞吗

学新通

创作不易,感谢你的支持!

本文使用 markdown.com.cn 排版

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhfhehei
系列文章
更多 icon
同类精品
更多 icon
继续加载