当前位置: 首页 > 科技观察

大家看得懂的Ahooks整体架构

时间:2023-03-17 15:25:28 科技观察

本文是浅显易懂的ahooks源码系列文章的第一篇。本系列的主要目标如下:加深对Reacthooks的理解。了解如何抽象自定义挂钩。构建您自己的React钩子库。培养阅读和学习源码的习惯,工具库是阅读源码的好选择。注:本系列ahooks源码分析基于v3.3.13。本人把源码抄了一份,主要是对源码做一些解读,详见[1]。第一部分主要介绍ahooks的背景和整体架构。Reacthooksutilslibrary自从React16.8发布Reacthooks之后,越来越多的项目使用FunctionComponent。Reacthooksutils库随即诞生,主要解决两个问题:公共逻辑的抽象。解决Reacthooks的缺点,比如闭包等。那么现在社区里比较好的ReactHooksutils库有哪些呢?react-use[2]是一个比较活跃的Reacthooksutils库,star数为29.6k。它非常强大,有100多个挂钩。如果需要更完整的功能,可以考虑选择react-use。如果不需要齐全的功能,只需要一些常用的功能,react-use可能有点多余。大家可以看看我们今天的主角——ahooks[3],目前有9.2kstar,也算是一个比较活跃的社区。ahooks简介官方介绍如下:ahooks,读作[e?h?ks],是一个优质可靠的ReactHooks库。在目前的React项目开发过程中,一套好用的ReactHooks库是必不可少的,希望ahooks能够成为你的选择。特点它具有以下特点:易于学习和使用。支持SSR。将访问DOM/BOM的方法放在useEffect中(服务端不会执行),避免服务端执行时报错。源码中可以看到很多isBrowser的判断,主要是为了区分浏览器环境和服务器环境。对输入输出函数做了特殊处理,避免了闭包问题。输入函数总是使用最新的副本。这是通过useRef实现的。输出函数和地址不会改变。这是通过useMemoizedFn(ahooks封装)实现的,其实现也是通过useRef实现的。我们稍后会提到。包含大量从业务中提取的高级Hooks。包含丰富的基础Hooks。使用TypeScript构建,提供完整的类型定义文件。您可以学习一些TypeScript技巧。Hooks类型ahooks提供了常用的基于UI、SideEffect、LifeCycle、State、DOM等类别的Hooks。如下图:ahooks整体架构项目启动,我们从一个民间拷贝的ahooks[4]开始,克隆它。yarnruninityarnstart如果可以成功运行服务,你会看到和官方文档一样的页面。整体结构可以从仓库根目录下的package.json中获取如下信息。文档使用的是dumi。它是组件开发场景的文档工具。该项目是一个monoRepo。它的项目管理是通过lerna[5]进行管理的。单元测试是开玩笑的。在它的目录结构中,可以看到仓库的公共文档存放在docs中。packages、hooks和use-url-state中存放了两个包。整体结构类似于dumi中给出的lerna项目的结构。每个包下的每个组件都可以编写相应的文件。不同的是,hooks中的每个组件都有一个额外的__tests__文件夹,用于编写单元测试。类似hooks的组织形式可以用下图大致概括ahooks的工程结构:hooks刚才说了ahooks采用了monoRepo的方式,我们的源码在packages中。让我们来看看钩子。首先查看packages/hooks/package.json。另外,使用useUrlState这个hook需要独立安装@ahooksjs/use-url-state,其源码在packages/use-url-state。我理解官方的意图是这个库依赖于react-router。可能有一些项目不需要使用它。提出它将有助于减小包的大小。npmi@ahooksjs/use-url-state-S返回包/挂钩。关注依赖关系和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指定依赖的包,然后插件导入或requires依赖包时,总是引用npm包宿主机环境统一安装,最终解决插件与依赖包不一致的问题。这里的宿主环境一般是指我们自己的项目本身。这对于打包npm包非常重要。当你写一个包a依赖另一个包b,而这个包b是一个常用的包,引用了这个包a的业务,建议写在peerDependencies中,避免重复下载/多版本共存。总结作为系列的第一篇文章,介绍了Reacthooksutils库的背景、ahooks的特点和整体架构,然后探讨了各种常见的hooks方法的实现,敬请期待。参考官方发布的ahooks:值得拥抱的ReactHooks工具库[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官方发布:值得拥抱的ReactHooks工具库:https://developer.aliyun.com/article/768059