ahooks的useRequest源码解读

 ahooks是一套高质量的hooks库,在React开发的过程,能够省下很多冗余代码,提高开发效率

在开启本文 ahooks 之前,首先要先了解一下什么是 React hooks

React hooks 是 React 在 16.8 版本之后推出的新功能,它的出现让 函数式组件 不再是 无状态组件,而是 拥有状态 以及 副作用

举个例子,以前写一个计数器组件,是这样的格式

c03b3e6cf68f734bfc1d4b99a0e0bef8.png

上面的代码,假如用函数的形式,那么是无法在组件里维护 num 这个数量的,也无法在组件里改变 num,在 num 变化时做出处理。最多只能通过 props,从父组件控制它,例如下面:

692284eb4141786fccfb129a9600df91.png

但是 hooks 出现之后,我们就可以在函数组件里维护状态和副作用。例如下面代码所示,就可以通过 useState 来维护一个状态 num,用 useEffectnum变化时做出一些处理

904237798534d398053815cc961793eb.png

hooks的好处还不止体现在这里,还体现在它可以 抽离共用逻辑。例如系统里有很多组件都需要设置 localStorage ,那其实可以写一个 useLocalStorage 来实现逻辑复用

11c72c9e0f7b8cac5da38fb7dd2d569c.png

使用的时候就可以:

187f3a833a3224e26d42efe29cd00471.png

这样的复用非常实用,而且大大减少了代码量。所以很多人尝试去抽离一些通用的逻辑出来,组成一个库,而 ahooks,就是这样的一个 hooks

01

ahooks

ahooks,官网定义为一个高质量可靠的 React hooks 库

0668fb5161d5b2fae78c744a98c6d724.png

事实上也确实如此,React的开发中用上hooks,会让业务逻辑更加简洁易写,比较有代表性的hooks比如:

  • useRequest

  • useAsyncEffect

  • useDebounceFn

  • useThrottleFn

其中,最为常用的就是 useRequest

02


useRequest

首先看到 packages/hooks/src/useRequest/src/useRequest.ts 里面的代码,发现它其实是返回了另一个函数 useRequestImplement

6b3cb2a464f770a97d796500a966c9a0.png

这时候,我们跳到 useRequestImplement 方法里面查看具体写了什么:

f21311ba751096a90e26b6d3a4183d79.png

在这里出现了很多新的 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类

33ed5db85a94ab3735a8ac75741ff0c0.png

这里内容有点多,我们先看下 Fetch 类型里面维护的状态:

32b9021c34fc3934f11ba307d4b37513.png

  • loading:表示当前是否还在请求中

  • params:代表请求携带的参数

  • data:请求返回的数据

  • error:请求过程中如果throw Error的话,就会到这个字段中

有了这些初始状态,我们就要开始请求了,最核心的方法就是 runAsync 方法

04


runAsync方法

e455d4267d9d31ef356becc36ccc7a6b.png

这里面可以看到是按照 onBefore 、onRequest、onSuccess、onError、onFinally 这个流程串联起来的。实际上真正发起请求的只有这一段

0f4deb4aea0ebc112314fd4d6a493512.png

通过调用 this.runPluginHandler 来执行各个时期的回调函数。而 this.runPluginHandler 实际也是遍历执行传递进来的插件函数

4ffc3a6cd8d11abdad463af8863a3afb.png

看懂上面这段 runAsync 代码之后,run 的代码也很容易理解了

fbfe92c12e95cd819cc039148312c4db.png

05


cancel方法

上面讲的都是如何用 run 方法进行请求,那假如我请求中途想取消怎么办呢。

这里开头维护了一个 count 变量,每次 run 的时候就赋值给 currentCount,并且 +1。到最后请求结束之后,会比对 count 和当前的数字是否一致假如不一致,那说明就不是同一次请求,返回一个空的 Promise

9a58d6ef5f73f39bc04446a3de7eb0dc.png

cancel 方法利用了这个原理,每次调用cancel的时候,就把count  + 1,那最后对比肯定就不一致了。起到了取消的效果

39c63d22c1e0bc87c7d5d169b5a20e34.png

06


mutate方法

使用上面 run 方法,我们完成正常请求过程。但是有时候我们可能想立刻改变数据,而不是等待请求返回,useRequest 提供了一个 “立刻改变数据” 的方法,叫mutate,原理也很简单,直接使用传入的值,或者函数进行赋值。这里就直接贴上源码

a02f6070f3f0e60a0ca7f8d96eca5ca2.png

07


refresh方法

refresh 方法实际上也是重新跑了一次 run

cf879d64f0017dc8c6d81ed7302565a4.png

以上就是 useRequest 源码分析的全部内容,欢迎大家点赞和评论

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值