ahooks的useRequest源码解读
“ ahooks是一套高质量的hooks库,在React开发的过程,能够省下很多冗余代码,提高开发效率”
在开启本文 ahooks 之前,首先要先了解一下什么是 React hooks
React hooks 是 React 在 16.8 版本之后推出的新功能,它的出现让 函数式组件 不再是 无状态组件,而是 拥有状态 以及 副作用。
举个例子,以前写一个计数器组件,是这样的格式
上面的代码,假如用函数的形式,那么是无法在组件里维护 num 这个数量的,也无法在组件里改变 num,在 num 变化时做出处理。最多只能通过 props,从父组件控制它,例如下面:
但是 hooks 出现之后,我们就可以在函数组件里维护状态和副作用。例如下面代码所示,就可以通过 useState 来维护一个状态 num,用 useEffect 在 num变化时做出一些处理
hooks的好处还不止体现在这里,还体现在它可以 抽离共用逻辑。例如系统里有很多组件都需要设置 localStorage ,那其实可以写一个 useLocalStorage 来实现逻辑复用
使用的时候就可以:
这样的复用非常实用,而且大大减少了代码量。所以很多人尝试去抽离一些通用的逻辑出来,组成一个库,而 ahooks,就是这样的一个 hooks 库
01
—
ahooks
ahooks,官网定义为一个高质量可靠的 React hooks 库
事实上也确实如此,React的开发中用上hooks,会让业务逻辑更加简洁易写,比较有代表性的hooks比如:
useRequest
useAsyncEffect
useDebounceFn
useThrottleFn
其中,最为常用的就是 useRequest
02
—
useRequest
首先看到 packages/hooks/src/useRequest/src/useRequest.ts 里面的代码,发现它其实是返回了另一个函数 useRequestImplement
这时候,我们跳到 useRequestImplement 方法里面查看具体写了什么:
在这里出现了很多新的 hooks,我们暂时不管,关注 fetchInstance这个实例,实际上是由 new Fetch 生成的,这个实例的对应关系如下图:
loading |
fetchInstance.state.loading |
data |
fetchInstance.state.data |
error |
fetchInstance.state.error |
params |
fetchInstance.state.params |
cancel |
fetchInstance.cancel |
refresh |
fetchInstance.refresh |
refreshAsync |
fetchInstance.refreshAsync |
run |
fetchInstance.run |
mutate |
fetchInstance.mutate |
那接下来,我们就着重看下 Fetch 这个类
03
—
Fetch类
这里内容有点多,我们先看下 Fetch 类型里面维护的状态:
loading:表示当前是否还在请求中
params:代表请求携带的参数
data:请求返回的数据
error:请求过程中如果throw Error的话,就会到这个字段中
有了这些初始状态,我们就要开始请求了,最核心的方法就是 runAsync 方法
04
—
runAsync方法
这里面可以看到是按照 onBefore 、onRequest、onSuccess、onError、onFinally 这个流程串联起来的。实际上真正发起请求的只有这一段
通过调用 this.runPluginHandler 来执行各个时期的回调函数。而 this.runPluginHandler 实际也是遍历执行传递进来的插件函数
看懂上面这段 runAsync 代码之后,run 的代码也很容易理解了
05
—
cancel方法
上面讲的都是如何用 run 方法进行请求,那假如我请求中途想取消怎么办呢。
这里开头维护了一个 count 变量,每次 run 的时候就赋值给 currentCount,并且 +1。到最后请求结束之后,会比对 count 和当前的数字是否一致,假如不一致,那说明就不是同一次请求,返回一个空的 Promise
cancel 方法利用了这个原理,每次调用cancel的时候,就把count + 1,那最后对比肯定就不一致了。起到了取消的效果
06
—
mutate方法
使用上面 run 方法,我们完成正常请求过程。但是有时候我们可能想立刻改变数据,而不是等待请求返回,useRequest 提供了一个 “立刻改变数据” 的方法,叫mutate,原理也很简单,直接使用传入的值,或者函数进行赋值。这里就直接贴上源码
07
—
refresh方法
refresh 方法实际上也是重新跑了一次 run
以上就是 useRequest 源码分析的全部内容,欢迎大家点赞和评论