1 什么是 ahooks
ahooks 是由阿里巴巴团队开发的一套高质量、可靠的 React Hooks 库,旨在通过封装常用业务逻辑,帮助开发者提升 React 应用开发效率。截至 2025 年 6 月,最新版本为 3.8.5,已在阿里内部数百个产品(如支付宝、淘宝、天猫)中投入生产使用,并支持服务器端渲染(SSR)、TypeScript 类型定义等企业级特性。
与社区其他 Hooks 库(如 react-use)相比,ahooks 的核心优势在于:
- 贴近业务场景 :提炼自阿里中台业务,提供如
useAntdTable
、usePagination
等高频场景 Hooks - 无闭包陷阱:所有输出函数引用地址固定,输入函数自动获取最新值
- 插件化设计 :核心功能(如
useRequest
)采用插件架构,支持按需扩展 - 严格兼容性:解决 React 严格模式(Strict Mode)和热更新(HMR)下的常见问题
2 安装与基础使用
2.1 环境准备
ahooks 要求 React 版本 ≥ 16.8.0(支持 Hooks 的最低版本),推荐使用 npm 或 yarn 安装:
bash
# npm
npm install ahooks --save
# yarn
yarn add ahooks
# pnpm
pnpm add ahooks
2.2 快速上手
以最常用的 useRequest
为例,实现一个数据请求组件:
jsx
import { useRequest } from 'ahooks'
function UserProfile() {
const { data, loading, error } = useRequest(
() => fetch('/api/user').then(res => res.json()),
{
refreshDeps: [], // 依赖变化时自动刷新
onSuccess: (result) => {
console.log('请求成功:', result)
}
}
)
if (loading) return <div>加载中...</div>
if (error) return <div>错误: {error.message}</div>
return (
<div>
<h2>{data.name}</h2>
<p>邮箱: {data.email}</p>
</div>
)
}
3 核心 Hooks 分类详解
3.1 状态管理 Hooks
3.1.1 useToggle:双向状态切换
简化 boolean 或双值状态切换逻辑,避免手动编写 setState(!state)
:
jsx
import { useToggle } from 'ahooks'
function ThemeSwitch() {
// 基础用法(布尔值)
const [darkMode, { toggle }] = useToggle(false)
// 自定义值切换
const [status, { setLeft, setRight }] = useToggle('online', 'offline')
return (
<div>
<button onClick={toggle}>
{darkMode ? '切换至亮色' : '切换至暗色'}
</button>
<div>当前状态: {status}</div>
<button onClick={setLeft}>上线</button>
<button onClick={setRight}>下线</button>
</div>
)
}
3.1.2 useLocalStorageState:持久化状态
将状态存储在 localStorage 中,页面刷新后自动恢复:
jsx
import { useLocalStorageState } from 'ahooks'
function SearchHistory() {
const [history, setHistory] = useLocalStorageState('search_history', {
defaultValue: []
})
const addSearch = (keyword) => {
setHistory(prev => [...new Set([keyword, ...prev])].slice(0, 10))
}
return (
<div>
<input
placeholder="搜索..."
onKeyPress={(e) => {
if (e.key === 'Enter') addSearch(e.target.value)
}}
/>
<ul>
{history.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
</div>
)
}
3.2 副作用处理 Hooks
3.2.1 useRequest:全能请求管理
ahooks 的明星 Hooks,封装了请求状态管理、缓存、轮询等 20+ 功能:
jsx
import { useRequest } from 'ahooks'
function ProductList() {
const {
data,
loading,
run,
refresh
} = useRequest(
({ current, pageSize, keyword }) =>
fetch(`/api/products?current=${current}&pageSize=${pageSize}&keyword=${keyword}`)
.then(res => res.json()),
{
manual: true, // 手动触发
defaultParams: [{ current: 1, pageSize: 10, keyword: '' }],
debounceInterval: 300, // 防抖
cacheKey: 'productList', // 缓存键
revalidateOnFocus: true, // 窗口聚焦时刷新
}
)
return (
<div>
<input
placeholder="搜索产品"
onChange={(e => {
run({ ...run.params[0], keyword: e.target.value })
})}
/>
<button onClick={refresh}>刷新</button>
{loading ? <div>加载中...</div> : (
<table>
{/* 表格内容 */}
</table>
)}
</div>
)
}
3.2.2 useDebounce:值防抖处理
延迟处理高频变化的值(如搜索输入):
jsx
import { useDebounce, useState } from 'ahooks'
function SearchBox() {
const [inputValue, setInputValue] = useState('')
// 延迟 500ms 处理输入值
const debouncedValue = useDebounce(inputValue, { wait: 500 })
// 仅在防抖值变化时触发搜索
useEffect(() => {
if (debouncedValue) {
searchApi(debouncedValue)
}
}, [debouncedValue])
return (
<input
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
placeholder="输入搜索关键词"
/>
)
}
3.3 DOM 操作 Hooks
3.3.1 useClickAway:点击外部关闭
检测点击事件是否发生在目标元素外部,常用于下拉菜单、模态框:
jsx
import { useRef, useState } from 'react'
import { useClickAway } from 'ahooks'
function Dropdown() {
const [visible, setVisible] = useState(false)
const ref = useRef(null)
// 点击外部区域关闭下拉菜单
useClickAway(() => {
setVisible(false)
}, ref, ['click']) // 监听 click 事件
return (
<div ref={ref} style={{ position: 'relative' }}>
<button onClick={() => setVisible(!visible)}>
下拉菜单
</button>
{visible && (
<div style={{
position: 'absolute',
top: '100%',
width: '200px',
border: '1px solid #ccc',
padding: '8px'
}}>
<div>菜单项 1</div>
<div>菜单项 2</div>
<div>菜单项 3</div>
</div>
)}
</div>
)
}
3.3.2 useVirtualList:大数据列表优化
虚拟滚动列表,只渲染可视区域内的项,支持十万级数据渲染:
jsx
import { useVirtualList } from 'ahooks'
function BigList() {
// 生成 10 万条测试数据
const data = Array.from({ length: 100000 }, (_, i) => ({
id: i,
content: `列表项 ${i + 1}`
}))
const { list, containerProps, wrapperProps } = useVirtualList(data, {
itemHeight: 50, // 每行高度
overscan: 5, // 视区外预渲染数量
})
return (
<div
{...containerProps}
style={{ height: '500px', overflow: 'auto', border: '1px solid #ccc' }}
>
<div {...wrapperProps}>
{list.map(item => (
<div
key={item.id}
style={{ height: '50px', padding: '16px', borderBottom: '1px solid #eee' }}
>
{item.data.content}
</div>
))}
</div>
</div>
)
}
3.4 场景类 Hooks
3.4.1 useAntdTable:Ant Design 表格集成
无缝整合 Ant Design Table 组件,自动处理分页、排序、筛选逻辑:
jsx
import { useAntdTable } from 'ahooks'
import { Table, Input, Button } from 'antd'
function UserTable() {
const [form] = Form.useForm()
const { tableProps, search } = useAntdTable(
async (params) => {
const { current, pageSize, ...rest } = params
const res = await fetch('/api/users', {
method: 'POST',
body: JSON.stringify({ page: current, size: pageSize, ...rest })
})
const data = await res.json()
return {
list: data.records,
total: data.total
}
},
{
form,
defaultPageSize: 10
}
)
return (
<div>
<Form form={form} layout="inline">
<Form.Item name="username" label="用户名">
<Input placeholder="请输入" />
</Form.Item>
<Form.Item>
<Button type="primary" onClick={search.submit}>搜索</Button>
<Button onClick={search.reset} style={{ marginLeft: 8 }}>重置</Button>
</Form.Item>
</Form>
<Table
{...tableProps}
columns={[
{ title: '用户名', dataIndex: 'username' },
{ title: '邮箱', dataIndex: 'email' },
{ title: '注册时间', dataIndex: 'registerTime' }
]}
/>
</div>
)
}
4 高级特性与最佳实践
4.1 避免闭包陷阱
ahooks 对所有输入输出函数做了特殊处理,解决 React Hooks 常见的闭包问题:
jsx
import { useInterval, useState } from 'ahooks'
function Timer() {
const [count, setCount] = useState(0)
// 即使没有将 count 加入依赖,也能获取最新值
useInterval(() => {
console.log('当前 count:', count) // 始终为最新值
}, 1000)
return <button onClick={() => setCount(c => c + 1)}>{count}</button>
}
4.2 插件化请求能力
useRequest
通过插件机制实现丰富功能,如轮询、重试、缓存:
jsx
// 轮询请求示例
const { data } = useRequest(fetchData, {
pollingInterval: 5000, // 每 5 秒轮询一次
pollingWhenHidden: false, // 页面隐藏时停止轮询
})
// 错误重试示例
const { data } = useRequest(fetchData, {
retryCount: 3, // 失败重试 3 次
retryInterval: 1000, // 重试间隔 1 秒
})
4.3 React 19 适配方案
虽然 ahooks 尚未官方支持 React 19,但可通过 package.json
临时适配:
json
{
"overrides": {
"ahooks": {
"react": "^19.0.0",
"react-dom": "^19.0.0"
}
}
}
⚠️ 注意:React 19 中移除了
element.ref
,可能导致部分 DOM 类 Hooks 出现警告,建议关注官方更新。
5 总结与资源
ahooks 作为成熟的 React Hooks 库,通过封装通用逻辑,显著减少了重复代码量(据统计平均减少 30%+ 状态管理代码)。其核心价值在于:
- 提升开发效率:无需重复实现防抖、节流、请求缓存等逻辑
- 保证代码质量:经过阿里内部数百个项目验证,处理了边缘场景
- 降低维护成本:统一的 API 设计,完善的 TypeScript 类型
官方资源
- 文档 :https://ahooks.js.org/
- GitHub :https://github.com/alibaba/hooks
- 更新日志 :https://github.com/alibaba/hooks/releases
通过合理使用 ahooks,开发者可以将精力集中在业务逻辑而非基础功能实现上,是 React 项目提升开发效率的重要工具。