在 React Hooks 成为事实标准之后,如何写出稳定、可维护、不踩坑的 Hooks 代码,成了每个中大型 React 项目绕不开的问题。
如果说 Hooks 改变了我们组织逻辑的方式,那么 ahooks 想做的事情更明确:
成为 React Hooks 领域里的 “lodash” —— 稳定、可靠、可长期依赖的基础设施。
从 2019 年 8 月第一个版本发布至今,ahooks 已经历多次重大演进,尤其是 3.0 版本之后,它的设计目标已经非常清晰:
高质量、强约束、可预期、面向真实业务场景。
ahooks 的发展背景
早期的 ahooks(也叫 umi hooks)更多是 “工具合集” 的形态,但随着项目规模增长,2.x 版本逐渐暴露出一些问题:
- 闭包问题频发
- SSR 支持不足
- API 设计不够统一
- 严格模式(Strict Mode)和 react-refresh 下行为异常
- DOM 相关 Hooks 对 target 变化支持不友好
ahooks 3.0 的目标非常明确:
建设一套「长期可依赖」的 React Hooks 基础库。
这也是为什么 ahooks 在 3.0 之后,整体设计风格明显趋于 保守、稳定、可推导。
ahooks 3.x 的核心优势
相较于 2.x,ahooks 3.x 带来了系统性的升级:
✅ 全面支持 SSR
所有 Hooks 都考虑了服务端渲染场景,不会再出现 window is not defined 这类问题。
✅ 全新的 useRequest
通过 插件化架构,把异步请求中常见的复杂逻辑统一收敛。
✅ 输出函数引用固定
所有返回的函数都经过特殊处理,避免闭包陷阱,这是 ahooks 最重要的设计理念之一。
✅ DOM Hooks 支持 target 动态变化
不再要求 target 一定是稳定引用,真实业务更友好。
✅ 更合理的 API 设计
统一的命名、参数顺序、返回结构,让 Hooks 更容易被“扫一眼就懂”。
✅ 严格模式 & react-refresh 友好
在 React 18 严格模式下不会产生副作用翻倍的问题。
✅ 更丰富的 Hooks 集合
覆盖从基础状态管理到复杂业务场景。
Hooks 分类一览
ahooks 并不是杂乱堆砌 Hooks,而是按 职责维度 进行分类:
- State:状态管理
useBoolean、useToggle、useSetState、useMap - SideEffect:副作用增强
useDebounceFn、useThrottleFn - LifeCycle:生命周期
useMount、useUnmount、useUpdate - DOM:DOM / 事件
useEventListener、useInViewport - UI / Business:业务增强
useRequest、useAntdTable - Advanced:高阶能力
useLatest、useMemoizedFn
这种分类方式,本身就是一份 Hooks 使用指南。
✨ 核心特性总结
- 🚀 易学易用,API 直观
- 🌐 全面支持 SSR
- 🧠 特殊处理输入 / 输出函数,规避闭包问题
- 🧩 大量提炼自真实业务的高级 Hooks
- 🧱 丰富且稳定的基础 Hooks
- 🧾 全量 TypeScript 类型支持
📦 安装
npm install ahooks
# or
yarn add ahooks
# or
pnpm add ahooks
# or
bun add ahooks
🔨 基本使用
import { useRequest } from 'ahooks';
快速上手:useRequest 才是核心王牌
如果只推荐 ahooks 里的一个 Hook,那一定是 useRequest。
它的定位非常明确:
React 项目里的异步数据管理,用 useRequest 就够了。
插件化能力一览
useRequest 并不是一个“巨无霸 Hook”,而是 核心极简 + 插件增强 的架构:
- 自动 / 手动请求
- 轮询
- 防抖 / 节流
- 屏幕聚焦重新请求
- 错误重试
- loading delay
- SWR(stale-while-revalidate)
- 请求缓存
你可以只用 10%,也可以叠满能力,但代码结构始终清晰。
useRequest 示例
const { data, loading, run } = useRequest(fetchUser, {
manual: true,
debounceWait: 300,
retryCount: 3,
});
👉 没有状态撕裂、没有额外 useEffect、没有胶水代码。
最佳实践清单(强烈推荐)
- ✅ 能用 useRequest,就别自己封 axios hooks
- ✅ 事件 / 定时器 / 订阅统一用
useMemoizedFn + useLatest - ✅ 表格页优先使用
useAntdTable - ✅ 用户输入触发请求,一定配
useDebounceFn - ✅ 弹窗 / 抽屉 / 开关统一用
useBoolean - ✅ UI 偏好持久化用
useLocalStorageState - ✅ 轮询及时
cancel - ✅ 依赖请求用
ready+refreshDeps - ✅ service 始终返回 Promise,类型要明确
- ✅ 对外只读数据,直接解构 data,别重复维护状态
这些实践,基本覆盖了 80% 的真实业务坑位。
常见坑 & 规避方式
1️⃣ 闭包问题
问题:定时器里拿到旧 state
方案:useLatest 或 useMemoizedFn
2️⃣ 过度重渲染
问题:回调每次 render 都变
方案:用 useMemoizedFn 替代 useCallback
3️⃣ 重复请求
问题:输入框触发请求太频繁
方案:useDebounceFn 或 debounceWait
4️⃣ 内存泄漏
问题:轮询 / 订阅没清理
方案:useRequest.cancel / useEventListener 自动清理
5️⃣ 缓存陷阱
问题:cacheKey + staleTime 数据不更新
方案:调整 staleTime,或 refresh / 修改 params
为什么说 ahooks 值得长期依赖?
很多 Hooks 库“好用”,但 ahooks 的特别之处在于克制:
- 不追新语法噱头
- 不强行抽象
- 设计目标始终围绕 真实业务复杂度
- 对 React 行为理解非常深入
如果你正在维护 中大型 React 项目,或者希望减少 Hooks 层面的心智负担,ahooks 几乎是 必选项。
ahooks 不是帮你写炫技代码,而是帮你少踩坑。
结语
当 Hooks 从“新特性”变成“基础设施”,
我们真正需要的是 稳定、可靠、可预期 的工具。
ahooks,正是为这个阶段而生。
如果你还在重复造轮子、修闭包、调请求状态,不妨认真把 ahooks 用起来一次。
文章评论