React 业务场景使用相关封装(hooks 使用)
React 业务场景相关方法封装(hooks 使用)
React 中常用的三方 hooks 库
库名 | 特点 | 常见场景 | 官方文档 |
---|---|---|---|
ahooks(阿里出品) | 丰富实用的 Hooks,和 Ant Design 配合最佳 | useRequest (请求管理)、useDebounce 、useLocalStorageState 、倒计时、节流 | https://ahooks.js.org/ |
React Query(TanStack Query) | 最强大的 服务端数据管理 库,缓存、重试、乐观更新 | API 请求、分页、数据缓存与同步 | https://tanstack.com/query/latest |
SWR(Vercel 出品) | 轻量级数据获取,基于 SWR 策略(Stale-While-Revalidate) | Next.js / CSR 数据获取、自动缓存 | https://swr.vercel.app/ |
react-use | 最全的 Hooks 工具库(涵盖浏览器 API、状态管理、UI 控制) | 本地存储、窗口大小、点击外部、全屏、鼠标状态 | https://github.com/streamich/react-use |
usehooks-ts | 简洁实用的小 Hook 集合 | useDarkMode 、useCopyToClipboard 、useOnClickOutside 、useWindowSize | https://usehooks-ts.com/ |
react-huse | 偏函数式编程的 Hooks 库 | 更偏小众,适合函数式风格项目 | https://github.com/streamich/react-huse |
react-use 相关使用
- 安装库 npm install react-use
- 按需 import { useXXX } from ‘react-use’
- 在组件内直接使用 Hook
- 官方文档有丰富示例,几乎涵盖所有常用场景
- GitHub
- Hook 列表与示例
Array 相关封装
场景:在开发中,经常需要对数组进行一些操作,如果直接使用原生方法可能会使代码看起来非常臃肿。
hook 封装:
import { useState, useCallback } from "react";/*** 通用数组 Hook* @param {Array} initialValue 初始数组*/
function useArrayState(initialValue = []) {const [array, setArray] = useState(initialValue);// 添加元素const push = useCallback((item) => {setArray((prev) => [...prev, item]);}, []);// 根据索引更新const updateByIndex = useCallback((index, newItem) => {setArray((prev) => {const newArr = [...prev];newArr[index] = newItem;return newArr;});}, []);// 根据 id 更新const updateById = useCallback((id, updater) => {setArray((prev) =>prev.map((item) =>item.id === id ? { ...item, ...updater(item) } : item));}, []);/*** ✅ 根据条件更新* @param {Function} predicate 条件函数* @param {Function} updater 更新函数* @param {"first"|"all"} mode 更新模式(默认 "all")*/const updateByCondition = useCallback((predicate, updater, mode = "all") => {setArray((prev) => {if (mode === "first") {const newArr = [...prev];const index = newArr.findIndex(predicate);if (index !== -1) {newArr[index] = { ...newArr[index], ...updater(newArr[index]) };}return newArr;}// 默认 all:更新所有满足条件的元素return prev.map((item) =>predicate(item) ? { ...item, ...updater(item) } : item);});}, []);// 删除元素(按索引)const removeByIndex = useCallback((index) => {setArray((prev) => prev.filter((_, i) => i !== index));}, []);// 删除元素(按 id)const removeById = useCallback((id) => {setArray((prev) => prev.filter((item) => item.id !== id));}, []);// 清空数组const clear = useCallback(() => setArray([]), []);return {array,setArray,push,updateByIndex,updateById,updateByCondition, // ✅ 新增,支持 "first" | "all"removeByIndex,removeById,clear,};
}export default useArrayState;
使用:
import React from "react";
import useArrayState from "./useArrayState";const Demo = () => {const { array, updateByCondition, push } = useArrayState([{ id: 1, name: "Alice", age: 20 },{ id: 2, name: "Bob", age: 25 },{ id: 3, name: "Charlie", age: 30 },]);return (<div><h3>数组管理示例</h3><pre>{JSON.stringify(array, null, 2)}</pre>{/* 更新第一个年龄大于 21 的用户 */}<buttononClick={() =>updateByCondition((item) => item.age > 21,() => ({ name: "🔥 First Updated" }),"first" // ✅ 只更新第一个符合条件的)}>更新第一个符合条件的用户</button>{/* 更新所有年龄大于 21 的用户 */}<buttononClick={() =>updateByCondition((item) => item.age > 21,() => ({ name: "🔥 All Updated" }),"all" // ✅ 默认,更新所有符合条件的)}>更新所有符合条件的用户</button><buttononClick={() => push({ id: Date.now(), name: "New User", age: 28 })}>添加新用户</button></div>);
};export default Demo;