更多的React-Hooks:ahooks到底有多好用

您好,我是沧沧凉凉,是一名前端开发者,目前在掘金知乎以及个人博客上同步发表一些学习前端时遇到的趣事和知识,欢迎关注。


这是学习React后的总结文章之一,通过React的学习,我打开了一个前端新世界。本篇文章要推荐的也是我在项目中使用的由蚂蚁生态开源的项目-ahooks

因为我之前都是写的Vue,所以会和Vue进行一些对比,当然这并不是说Vue不好,Vue是一个非常完善以及易上手的框架,而且很多解决方案都由官方进行提供,比如组件的缓存机制,配置路由,反观React,官方提供的东西非常少,几乎完全是靠React庞大的社区进行支撑。

如果是跨行业的朋友,首先推荐学习Vue,因为目前就国内来说Vue的工作机会远远多于React,只要你肯学,相信找到一份前端工作并不困难。

1. useRequest

最为常用的Hook,几乎使用ahooks主要就是为了使用该Hook,它是一个强大的管理异步数据请求的Hook,试想一下,如果你在Vue中,你要进行一个网络请求你一般会怎么做?

是不是先创建一个请求函数,然后在methods中封装一个方法,调用这个方法,将请求到的结果赋值给data里面的状态,以方便在界面上进行调用,例如下面的代码:

// 创建请求函数
export const testRequest = ()=>{
  return new Promise((res)=>{
    setTimeout(()=>{
      res({
        code:200,
        success:true,
        data:"模拟请求"
      })
    },1000)
  })
}


data() {
  return {
    data: {},
  };
},
created() {
  // 进行请求
  this.request();
},
methods: {
  request() {
    testRequest().then((res) => {
      // 存储数据
      this.data = res;
    });
  },
},

但是如果你需要一个loading状态呢,你是不是还得在data里面声明一个loading属性,然后在methods调用请求函数之前将loading赋值为true然后在调用完后将loading赋值为false

如果你这个时候还需要防抖和节流呢?那你是不是还得在请求函数外面包一层防抖或节流函数呢?

如果这个请求要隔一段时间就发起一次(轮询),你是不是还得搞一个定时器,如果搞了定时器,又必须在组件销毁的时候销毁定时器,不然可能会造成内存泄露。

如果是一个请求做完这些工作可能还好,如果多个请求都需要实现上面的这些功能呢?

当然很多功能你都可以封装一个通用的函数进行实现,但是如果你想要在Vue2中的界面上进行展示这个状态,就必须在data中声明一个属性进行接收。这也就造成可能每个界面你都会创建一个dataloading属性,然后进行赋值,如果你想要接收一个错误状态error,那你还需要声明一个error属性。

当然mixin可以解决这个重复声明的问题,但是我个人推荐,**能不用mixin的尽量不要使用mixin**,WebStorm还好,就算是在调用mixin中声明的属性,也可以正确的指向来源,如果你使用其它编辑器,你可能根本不知道该属性究竟是声明在哪儿的,尤其是在mixin层层嵌套的情况下,正所谓写代码一时爽,别人维护火葬场。

而这一切在React中,通过useRequest这个Hook,它帮你完成了上面所述的所有功能,你只需要做一个步骤,那就是创建一个请求函数,然后调用这个Hook,就是这么的简单,直接上代码:

const { data, error, loading, run } = useRequest(testRequest);
  • data:请求成功的返回值。
  • error:错误时返回的信息。
  • loading:请求是否完成。
  • run:一个函数,调用它就可以进行重复请求。

防抖和节流还有轮询就更简单了,该Hook除了接受一个函数当做参数外,还接受一个对象可以对它进行配置。

const { data, error, loading } = useRequest(testRequest, {
  // 开启防抖
  debounceInterval: 500,
  // 开启节流
  throttleInterval: 500// 开启轮询
  pollingInterval: 500
});

是不是很神奇?在Vue的代码中要做到这些可不太容易,而在React中使用Hook就可以很轻松的做到这些,大大的减少了重复代码量。

它的功能还不仅仅只有上面的那些,更多的功能可以直接看官方文档

2. useVirtualList

React中有很多关于性能优化的方式,而且社区也提供了大量的性能优化方案,比如这个useVirtualList

试想一个场景,如果一个列表拥有很大的数据量,数据量达到几万条,大部分人的解决方案都是懒加载,即当滚动条快要触底的时候加载部分剩余的内容,但其实这样会造成一个不好的体验,如果用户想快速下拉看最后一条数据,他就会经过多次下拉触底,触发动态加载的过程。

但是如果有需求是客户可以直接通过滚动条拉到最后一条数据呢?其实渲染DOM是非常消耗性能的一件事情,而在一个页面中,最多也仅仅只能渲染出几百个DOM节点,达到上千DOM节点时浏览器就可能出现内存泄露,卡死等情况。

而虚拟列表就是为了解决这个问题,即一次性请求完大量的数据,仅渲染可见范围以及可见范围上下的某一片段数据,然后根据数据量计算出一个虚拟滚动条,实现的效果也就像真的同时渲染出过万个DOM节点一样。可以看一下实际效果:

useVirtualList

3. useSize

一个用于监听dom节点尺寸变化的Hook。

使用非常方便,它有很多用途,同时它也可以用来做过渡动画。

当你在做一个点击就伸展出来的窗口组件:

size

该组件高度不能进行固定,因为它的高度会随着组件调用时里面内容的高度而发生改变,但是高度不能固定的话实现这种过渡动画就有难度,从上面的动图就可以看出来,如果高度固定了可能就会出现留白或者高度不够的情况。

所以这个时候我们可以使用useSize来监听组件内部高度的变化,就可以达到下面的效果:

useSize

即使内容发生了变化,依然也会有一个过渡效果,是不是非常方便,具体使用方式可以直接看官方文档

4. useInViewport

一个用于判断dom元素是否在可视范围之内的Hook。

有时候我们做一些官网通常会给一些动画,但是这些动画这就会存在一个问题,因为所有动画的加载都是在页面渲染完成后,也就是有些页面比较长,可能用户的可见范围都还没有到那里,动画已经播放完了。

而使用该Hook就可以判断该dom是否已经在可见范围内,如果在可见范围内就可以动态添加一个动画,这样每次在可见范围内都会触发这个动画。

光说不练,直接看一下效果吧:

useInViewport

可以看到在dom元素出现在可见范围内时,才会触发动画,当然,这么做肯定是不专业的,而且也存在着很多问题,比如图上可能会出现延迟触发的情况,如果你想比较专业并且完美的实现这种效果,推荐使用非常强大的动画库GSAP,我在之前也写过相关的文章。

5. 持久化存储

分别有useSessionStorageStateuseLocalStorageStateuseCookieState,都是ahooks提供的状态持久化存储Hook。专门用于在组件中使用存储状态。

使用方法也很简单,就不在这里过多解释了,最重要的是useSessionStorageStateuseLocalStorageState支持自动序列化,也就是说你可以直接存储对象,它会帮你自动序列化成字符串,而你在界面上调用时,它也会帮你自动转化为对象。

6. 最后

本篇文章仅仅是起到一个抛砖引玉的作用,具体没有讲解过多的用法,因为官方文档写的实在是太全面了,所以仅仅只是给出了一些Hook在项目中的应用场景。

ahooks还提供了大量的好用的Hook,例如防抖、节流、定时器,例如Map和Set的一些处理,还有判断鼠标位置,滚动状态等等,这里就不多讲了,推荐将官方文档上面写到的所有Hook都看一遍,有一个印象,之后遇到问题的时候再去翻阅相关的内容就可以了。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!