React强大且灵活hooks库——ahooks入门实践介绍

简介

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 库,通过本文的介绍和实践,您应该能够:

  1. 理解 ahooks 的核心概念和设计理念
  2. 掌握常用 Hooks 的使用方法
  3. 在实际项目中正确使用 ahooks
  4. 遵循最佳实践,提高代码质量

React强大且灵活hooks库------ahooks入门实践介绍 - 高质量源码分享平台-免费下载各类网站源码与模板及前沿动态资讯

相关推荐
2501_9209317016 分钟前
React Native鸿蒙跨平台实现推箱子游戏,完成玩家移动与箱子推动,当所有箱子都被推到目标位置时,玩家获胜
javascript·react native·react.js·游戏·ecmascript·harmonyos
layman05281 小时前
webpack5 css-loader:从基础到原理
前端·css·webpack
半桔1 小时前
【前端小站】CSS 样式美学:从基础语法到界面精筑的实战宝典
前端·css·html
AI老李1 小时前
PostCSS完全指南:功能/配置/插件/SourceMap/AST/插件开发/自定义语法
前端·javascript·postcss
_OP_CHEN1 小时前
【前端开发之CSS】(一)初识 CSS:网页化妆术的终极指南,新手也能轻松拿捏页面美化!
前端·css·html·网页开发·样式表·界面美化
啊哈一半醒1 小时前
CSS 主流布局
前端·css·css布局·标准流 浮动 定位·flex grid 响应式布局
PHP武器库1 小时前
ULUI:不止于按钮和菜单,一个专注于“业务组件”的纯 CSS 框架
前端·css
电商API_180079052471 小时前
第三方淘宝商品详情 API 全维度调用指南:从技术对接到生产落地
java·大数据·前端·数据库·人工智能·网络爬虫
晓晓莺歌1 小时前
vue3某一个路由切换,导致所有路由页面均变成空白页
前端·vue.js
Up九五小庞2 小时前
开源埋点分析平台 ClkLog 本地部署 + Web JS 埋点测试实战--九五小庞
前端·javascript·开源