所有分类
  • 所有分类
  • Html5资源
  • React资源
  • Vue资源
  • Php资源
  • ‌小程序资源
  • Python资源

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. 遵循最佳实践,提高代码质量

参考资源

资源下载
下载价格免费
注意:本网站资源属于虚拟产品,不支持退款。请谨慎购买! 购买后资源无法下载,请联系客服QQ:844475003,微信号:th844475003。
原文链接:https://code.ifrontend.net/archives/773,转载请注明出处。
0

评论0

显示验证码
没有账号?注册  忘记密码?