本文是深入浅出 ahooks 源码系列文章的第二篇,这个系列的目标主要有以下几点:
-
加深对 React hooks 的理解。 -
学习如何抽象自定义 hooks。构建属于自己的 React hooks 工具库。 -
培养阅读学习源码的习惯,工具库是一个对源码阅读不错的选择。
注:本系列对 ahooks 的源码解析是基于 v3.3.13
。自己 folk 了一份源码,主要是对源码做了一些解读,可见 详情。
系列文章:
本文来讲下 ahooks 的核心 hook —— useRequest。
useRequest 简介
根据官方文档的介绍,useRequest 是一个强大的异步数据管理的 Hooks,React 项目中的网络请求场景使用 useRequest 就够了。
useRequest 通过插件式组织代码,核心代码极其简单,并且可以很方便的扩展出更高级的功能。目前已有能力包括:
-
自动请求/手动请求 -
轮询 -
防抖 -
节流 -
屏幕聚焦重新请求 -
错误重试 -
loading delay -
SWR(stale-while-revalidate) -
缓存
这里可以看到 useRequest 的功能是非常强大的,如果让你来实现,你会如何实现?也可以从介绍中看到官方的答案——插件化机制。
架构
如上图所示,我把整个 useRequest 分成了几个模块。
-
入口 useRequest。它负责的是初始化处理数据以及将结果返回。 -
Fetch。是整个 useRequest 的核心代码,它处理了整个请求的生命周期。 -
plugin。在 Fetch 中,会通过插件化机制在不同的时机触发不同的插件方法,拓展 useRequest 的功能特性。 -
utils 和 types.ts。提供工具方法以及类型定义。
useRequest 入口处理
先从入口文件开始,packages/hooks/src/useRequest/src/useRequest.ts
。
function useRequest<TData, TParams extends any[]>(
service: Service<TData, TParams>,
options?: Options<TData, TParams>,
plugins?: Plugin<TData, TParams>[],
) {
return useRequestImplement<TData, TParams>(service, options, [
// 插件列表,用来拓展功能,一般用户不使用。文档中没有看到暴露 API
...(plugins || []),
useDebouncePlugin,
useLoadingDelayPlugin,
usePollingPlugin,
useRefreshOnWindowFocusPlugin,
useThrottlePlugin,
useAutoRunPlugin,
useCachePlugin,
useRetryPlugin,
] as Plugin<TData, TParams>[]);
}
export default useRequest;
这里第一(service 请求实例)第二个参数(配置选项),我们比较熟悉,第三个参数文档中没有提及,其实就是插件列表,用户可以自定义插件拓展功能。
可以看到返回了 useRequestImplement
方法。主要是对 Fetch 类进行实例化。