简介
ahooks 前端开发的 React Hooks 库,提供了大量实用的自定义 Hooks,帮助开发者快速构建高质量的 React 应用。它遵循 React Hooks 的设计理念,提供了丰富的功能,涵盖了状态管理、网络请求、DOM 操作、工具函数等多个方面。
主要特点
- 开箱即用:提供 80+ 个实用的 Hooks
- TypeScript 支持:完整的 TypeScript 类型定义
- 轻量级:按需引入,支持 Tree Shaking
- 易学易用:API 设计简洁,学习成本低
- 社区活跃:持续更新维护,文档完善
安装和配置
安装依赖
npm install ahooks
示例
useRequest – 网络请求管理
import { useRequest } from "ahooks";
function UserList() {
const { data, loading, error } = useRequest(
async () => {
const response = await fetch("/api/users");
return response.json();
},
{
onSuccess: (data) => {
console.log("请求成功:", data);
},
onError: (error) => {
console.error("请求失败:", error);
},
}
);
return (
<div>
{loading && <div>加载中...</div>}
{error && <div>错误: {error.message}</div>}
{data && (
<ul>
{data.map((user) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
)}
</div>
);
}
如果设置了 options.manual = true,则 useRequest 不会默认执行,需要通过 run 来触发执行。
const { run } = useRequest(queryData, {
manual: true,
});
useSetState – 对象状态管理
import { useSetState } from "ahooks";
function UserForm() {
const [user, setUser] = useSetState({
name: "",
email: "",
});
const handleChange = (field: string, value: any) => {
setUser({ [field]: value });
};
return (
<form>
<input
value={user.name}
onChange={(e) => handleChange("name", e.target.value)}
placeholder="姓名"
/>
<input
value={user.email}
onChange={(e) => handleChange("email", e.target.value)}
placeholder="邮箱"
/>
</form>
);
}
useClickAway – 点击外部关闭
import { useClickAway } from "ahooks";
import { useRef, useState } from "react";
function Dropdown() {
const [visible, setVisible] = useState(false);
const ref = useRef();
useClickAway(() => {
setVisible(false);
}, ref);
return (
<div ref={ref} style={{ position: "relative" }}>
<button onClick={() => setVisible(!visible)}>下拉菜单</button>
{visible && (
<div
style={{
position: "absolute",
top: "100%",
border: "1px solid #ccc",
}}
>
<div>菜单项 1</div>
<div>菜单项 2</div>
<div>菜单项 3</div>
</div>
)}
</div>
);
}
useSize – 监听元素尺寸变化
import { useSize } from "ahooks";
import { useRef } from "react";
function ResizableComponent() {
const ref = useRef();
const size = useSize(ref);
return (
<div ref={ref} style={{ border: "1px solid #ccc", padding: "20px" }}>
<p>
当前尺寸: {size?.width} x {size?.height}
</p>
<p>调整浏览器窗口大小来查看效果</p>
</div>
);
}
useLocalStorageState – 本地存储状态
import { useLocalStorageState } from "ahooks";
function ThemeSwitcher() {
const [theme, setTheme] = useLocalStorageState("theme", {
defaultValue: "light",
});
return (
<div>
<p>当前主题: {theme}</p>
<button onClick={() => setTheme("light")}>浅色主题</button>
<button onClick={() => setTheme("dark")}>深色主题</button>
</div>
);
}
useDebounceFn – 防抖函数
import { useDebounceFn } from "ahooks";
import { useState } from "react";
function SearchInput() {
const [searchTerm, setSearchTerm] = useState("");
const { run: debouncedSearch } = useDebounceFn(
(value) => {
console.log("搜索:", value);
// 执行搜索逻辑
},
{ wait: 500 } // 500ms 防抖
);
const handleChange = (e) => {
const value = e.target.value;
setSearchTerm(value);
debouncedSearch(value);
};
return (
<input value={searchTerm} onChange={handleChange} placeholder="搜索..." />
);
}
综合示例 – TodoList
让我们通过一个完整的待办事项应用来实践 ahooks 的使用:
import React from "react";
import { useLocalStorageState } from "ahooks";
function TodoList() {
// 使用本地存储保存待办事项
const [todos, setTodos] = useLocalStorageState("todos", {
defaultValue: [],
});
const [inputValue, setInputValue] = React.useState("");
// 添加待办事项
const addTodo = () => {
if (!inputValue.trim()) return;
const newTodo = {
id: Date.now(),
text: inputValue.trim(),
completed: false,
};
setTodos([...todos, newTodo]);
setInputValue("");
};
// 切换完成状态
const toggleTodo = (id) => {
setTodos(
todos.map((todo) =>
todo.id === id ? { ...todo, completed: !todo.completed } : todo
)
);
};
// 删除待办事项
const deleteTodo = (id) => {
setTodos(todos.filter((todo) => todo.id !== id));
};
// 处理回车键
const handleKeyPress = (e) => {
if (e.key === "Enter") {
addTodo();
}
};
return (
<div className="min-h-screen bg-gray-50 py-8 px-4">
<div className="max-w-md mx-auto">
<h1 className="text-2xl font-bold text-center text-gray-800 mb-6">
Todo List
</h1>
{/* 添加待办事项 */}
<div className="bg-white rounded-lg shadow-sm p-4 mb-4">
<div className="flex gap-2">
<input
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
onKeyPress={handleKeyPress}
placeholder="添加新的待办事项..."
className="flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
<button
onClick={addTodo}
disabled={!inputValue.trim()}
className="px-4 py-2 bg-blue-500 text-white rounded-md hover:bg-blue-600 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
>
添加
</button>
</div>
</div>
{/* 待办事项列表 */}
<div className="space-y-2">
{todos.length === 0 ? (
<div className="bg-white rounded-lg shadow-sm p-8 text-center">
<p className="text-gray-500">还没有待办事项</p>
</div>
) : (
todos.map((todo) => (
<div
key={todo.id}
className="bg-white rounded-lg shadow-sm p-4 flex items-center gap-3"
>
<input
type="checkbox"
checked={todo.completed}
onChange={() => toggleTodo(todo.id)}
className="w-4 h-4 text-blue-500 rounded focus:ring-blue-500"
/>
<span
className={`flex-1 ${
todo.completed
? "line-through text-gray-400"
: "text-gray-800"
}`}
>
{todo.text}
</span>
<button
onClick={() => deleteTodo(todo.id)}
className="text-red-500 hover:text-red-700 transition-colors text-sm"
>
删除
</button>
</div>
))
)}
</div>
{/* 统计信息 */}
{todos.length > 0 && (
<div className="bg-white rounded-lg shadow-sm p-4 mt-4">
<div className="text-sm text-gray-600 flex justify-between items-center">
<span>总计: {todos.length} 项</span>
<span>已完成: {todos.filter((t) => t.completed).length} 项</span>
</div>
</div>
)}
</div>
</div>
);
}
export default TodoList;

常用 Hooks 速查表
Hook | 用途 | 示例 |
---|---|---|
useRequest | 网络请求管理 | 数据获取、提交表单 |
useSetState | 对象状态管理 | 表单状态、复杂状态 |
useLocalStorageState | 本地存储状态 | 用户偏好、缓存数据 |
useSessionStorageState | 会话存储状态 | 临时数据 |
useClickAway | 点击外部关闭 | 下拉菜单、模态框 |
useSize | 监听元素尺寸 | 响应式布局 |
useDebounceFn | 防抖函数 | 搜索输入、窗口调整 |
useThrottleFn | 节流函数 | 滚动事件、按钮点击 |
useInterval | 定时器 | 轮询、倒计时 |
useTimeout | 延时执行 | 延迟操作 |
usePrevious | 获取前一个值 | 比较变化 |
useUpdateEffect | 更新时执行 | 依赖变化时执行 |
useBoolean | 布尔状态管理 | 开关状态 |
useCounter | 计数器状态 | 分页、数量控制 |
总结
ahooks 是一个功能强大且易用的 React Hooks 库,通过本文的介绍和实践,您应该能够:
- 理解 ahooks 的核心概念和设计理念
- 掌握常用 Hooks 的使用方法
- 在实际项目中正确使用 ahooks
- 遵循最佳实践,提高代码质量
参考资源
原文链接:https://code.ifrontend.net/archives/773,转载请注明出处。
评论0