更多的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
中声明一个属性进行接收。这也就造成可能每个界面你都会创建一个data
和loading
属性,然后进行赋值,如果你想要接收一个错误状态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节点一样。可以看一下实际效果:
3. useSize
一个用于监听dom节点尺寸变化的Hook。
使用非常方便,它有很多用途,同时它也可以用来做过渡动画。
当你在做一个点击就伸展出来的窗口组件:
该组件高度不能进行固定,因为它的高度会随着组件调用时里面内容的高度而发生改变,但是高度不能固定的话实现这种过渡动画就有难度,从上面的动图就可以看出来,如果高度固定了可能就会出现留白或者高度不够的情况。
所以这个时候我们可以使用useSize
来监听组件内部高度的变化,就可以达到下面的效果:
即使内容发生了变化,依然也会有一个过渡效果,是不是非常方便,具体使用方式可以直接看官方文档。
4. useInViewport
一个用于判断dom元素是否在可视范围之内的Hook。
有时候我们做一些官网通常会给一些动画,但是这些动画这就会存在一个问题,因为所有动画的加载都是在页面渲染完成后,也就是有些页面比较长,可能用户的可见范围都还没有到那里,动画已经播放完了。
而使用该Hook就可以判断该dom是否已经在可见范围内,如果在可见范围内就可以动态添加一个动画,这样每次在可见范围内都会触发这个动画。
光说不练,直接看一下效果吧:
可以看到在dom元素出现在可见范围内时,才会触发动画,当然,这么做肯定是不专业的,而且也存在着很多问题,比如图上可能会出现延迟触发的情况,如果你想比较专业并且完美的实现这种效果,推荐使用非常强大的动画库GSAP,我在之前也写过相关的文章。
5. 持久化存储
分别有useSessionStorageState
、useLocalStorageState
、useCookieState
,都是ahooks提供的状态持久化存储Hook。专门用于在组件中使用存储状态。
使用方法也很简单,就不在这里过多解释了,最重要的是useSessionStorageState
和useLocalStorageState
支持自动序列化,也就是说你可以直接存储对象,它会帮你自动序列化成字符串,而你在界面上调用时,它也会帮你自动转化为对象。
6. 最后
本篇文章仅仅是起到一个抛砖引玉的作用,具体没有讲解过多的用法,因为官方文档写的实在是太全面了,所以仅仅只是给出了一些Hook在项目中的应用场景。
ahooks还提供了大量的好用的Hook,例如防抖、节流、定时器,例如Map和Set的一些处理,还有判断鼠标位置,滚动状态等等,这里就不多讲了,推荐将官方文档上面写到的所有Hook都看一遍,有一个印象,之后遇到问题的时候再去翻阅相关的内容就可以了。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!