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;