在前端开发中,数据请求是常见的操作,而阿里开源的ahooks库中的useRequest是一个非常实用的React Hook,它简化了数据请求的管理。但在实际使用中,我们经常会遇到需要统一处理loading状态防抖动的问题。本文将介绍如何封装useRequest,统一增加loadingDelay功能。
1.为什么需要loadingDelay防抖动
在用户交互频繁的场景下,比如搜索框输入、频繁切换选项卡等,如果不做防抖动处理,会导致:
频繁触发数据请求,增加服务器压力
页面loading状态快速闪烁,用户体验不佳
可能导致请求顺序错乱,显示错误数据
2.原生useRequest的局限性
ahooks的useRequest虽然支持loadingDelay参数,但存在以下问题:
每个调用处都需要单独设置loadingDelay
团队不同成员可能设置不同的延迟时间,导致体验不一致
修改全局默认值需要修改多处代码
3.封装实现方案
我们可以创建一个高阶Hook来统一处理这个问题:
import { useRequest } from 'ahooks';
import { Options, Plugin, Service } from 'ahooks/lib/useRequest/src/types';
export default function useReq<TData, TParams extends any[]>(
service: Service<TData, TParams>,
options?: Options<TData, TParams>,
plugins?: Plugin<TData, TParams>[]
) {
return useRequest(
service,
{
loadingDelay: 300,
...options,
},
plugins
);
}
4.使用示例
import useReq from "@/components/use-request";
function Demo() {
// 自动应用300ms的loadingDelay
const { data, loading } = useReq(async () => {
return fetch('/api/data').then(res => res.json());
});
// 可以覆盖默认值
const { data: searchData, loading: searchLoading } = useReq(
async (keyword: string) => {
return fetch(`/api/search?q=${keyword}`).then(res => res.json());
},
// 覆盖为500ms
{ loadingDelay: 500 }
);
return (
<div>
{loading ? <div>加载中...</div> : <div>{JSON.stringify(data)}</div>}
</div>
);
}