什么是 ahooks?
ahooks 是一个 React Hooks 库,提供了大量实用的自定义 hooks,帮助开发者更高效地构建 React 应用。其中状态管理类 hooks 是 ahooks 的一个重要分类,专门用于简化 React 状态的管理和操作。
安装 ahooks
npm install ahooks
状态管理类 hooks 详解
useSetState – 对象状态管理
useSetState
用于管理对象类型的状态,提供类似 setState
的 API。
import React from "react";
import { useSetState } from "ahooks";
import { Button, Card, Input } from "antd";
const UseSetStateExample = () => {
const [state, setState] = useSetState({
name: "张三",
age: 25,
email: "zhangsan@example.com",
});
const handleUpdateName = () => {
setState({ name: "李四" });
};
const handleUpdateAge = () => {
setState((prev) => ({ age: prev.age + 1 }));
};
const handleReset = () => {
setState({
name: "张三",
age: 25,
email: "zhangsan@example.com",
});
};
return (
<Card title="useSetState 对象状态管理">
<div style={{ marginBottom: 16 }}>
<p>
<strong>姓名:</strong> {state.name}
</p>
<p>
<strong>年龄:</strong> {state.age}
</p>
<p>
<strong>邮箱:</strong> {state.email}
</p>
</div>
<div>
<Button onClick={handleUpdateName} style={{ marginRight: 8 }}>
更新姓名
</Button>
<Button onClick={handleUpdateAge} style={{ marginRight: 8 }}>
增加年龄
</Button>
<Button onClick={handleReset}>重置</Button>
</div>
</Card>
);
};
useBoolean – 布尔值状态管理
useBoolean
用于管理布尔值状态,提供便捷的切换方法。
import React from "react";
import { useBoolean } from "ahooks";
import { Button, Card, Switch } from "antd";
const UseBooleanExample = () => {
const [state, { toggle, setTrue, setFalse }] = useBoolean(false);
return (
<Card title="useBoolean 布尔值状态管理">
<div style={{ marginBottom: 16 }}>
<p>
<strong>当前状态:</strong> {state ? "开启" : "关闭"}
</p>
<Switch checked={state} onChange={toggle} />
</div>
<div>
<Button onClick={toggle} style={{ marginRight: 8 }}>
切换
</Button>
<Button onClick={setTrue} style={{ marginRight: 8 }}>
设为开启
</Button>
<Button onClick={setFalse}>设为关闭</Button>
</div>
</Card>
);
};
useToggle – 切换状态管理
useToggle
用于在两个值之间切换状态。
import React from "react";
import { useToggle } from "ahooks";
import { Button, Card, Tag } from "antd";
const UseToggleExample = () => {
const [state, { toggle, setLeft, setRight }] = useToggle("light", "dark");
return (
<Card title="useToggle 切换状态管理">
<div style={{ marginBottom: 16 }}>
<p>
<strong>当前主题:</strong> <Tag color="blue">{state}</Tag>
</p>
</div>
<div>
<Button onClick={toggle} style={{ marginRight: 8 }}>
切换主题
</Button>
<Button onClick={setLeft} style={{ marginRight: 8 }}>
浅色主题
</Button>
<Button onClick={setRight}>深色主题</Button>
</div>
</Card>
);
};
useUrlState – URL 状态管理
useUrlState
用于将状态同步到 URL 参数中。
import React, { useState, useCallback } from "react";
import { Button, Card } from "antd";
// 自定义 useUrlState hook
const useUrlState = (initialState = {}) => {
const [state, setState] = useState(() => {
const urlParams = new URLSearchParams(window.location.search);
const result = {};
Object.keys(initialState).forEach((key) => {
result[key] = urlParams.get(key) || initialState[key];
});
return result;
});
const updateState = useCallback(
(newState) => {
const urlParams = new URLSearchParams(window.location.search);
if (typeof newState === "function") {
newState = newState(state);
}
Object.entries(newState).forEach(([key, value]) => {
if (value === undefined || value === null) {
urlParams.delete(key);
} else {
urlParams.set(key, String(value));
}
});
const newUrl = `${window.location.pathname}?${urlParams.toString()}`;
window.history.pushState({}, "", newUrl);
setState((prev) => ({ ...prev, ...newState }));
},
[state]
); return [state, updateState]; }; const UseUrlStateExample = () => { const [state, setState] = useUrlState({ page: “1” }); return ( <div> <Card title=”useUrlState URL 状态管理”> <p> <strong>当前页码:</strong> {state.page} <span style={{ paddingLeft: 8 }}> <Button size=”small” onClick={() => { setState((s) => ({ page: Number(s.page) + 1 })); }} style={{ marginRight: 4 }} > + </Button> <Button size=”small” onClick={() => { setState((s) => ({ page: Number(s.page) – 1 })); }} style={{ marginRight: 4 }} > – </Button> <Button size=”small” onClick={() => { setState({ page: undefined }); }} > reset </Button> </span> </p> <p style={{ marginTop: 8, fontSize: “12px”, color: “#666” }}> URL: {window.location.href} </p> </Card> </div> ); };
useCookieState – Cookie 状态管理
useCookieState
用于将状态同步到 Cookie 中。
import React from "react";
import { useCookieState } from "ahooks";
import { Input, Button, Card } from "antd";
const UseCookieStateExample = () => {
const [username, setUsername] = useCookieState("username", "");
const [theme, setTheme] = useCookieState("theme", "light");
return (
<Card title="useCookieState Cookie 状态管理">
<div style={{ marginBottom: 16 }}>
<Input
placeholder="用户名"
value={username}
onChange={(e) => setUsername(e.target.value)}
style={{ marginBottom: 8 }}
/>
<p>
<strong>当前主题:</strong> {theme}
</p>
</div>
<div>
<Button onClick={() => setTheme("light")} style={{ marginRight: 8 }}>
浅色主题
</Button>
<Button onClick={() => setTheme("dark")} style={{ marginRight: 8 }}>
深色主题
</Button>
<Button onClick={() => setUsername("")}>清空用户名</Button>
</div>
</Card>
);
};
useLocalStorageState – 本地存储状态管理
useLocalStorageState
用于将状态同步到 localStorage 中。
import React from "react";
import { useLocalStorageState } from "ahooks";
import { Input, Button, Card } from "antd";
const UseLocalStorageStateExample = () => {
const [notes, setNotes] = useLocalStorageState("notes", "");
return (
<Card title="useLocalStorageState 本地存储状态管理">
<div style={{ marginBottom: 16 }}>
<Input.TextArea
placeholder="输入笔记"
value={notes}
onChange={(e) => setNotes(e.target.value)}
rows={3}
style={{ marginBottom: 8 }}
/>
<p>
<strong>字符计数:</strong> {notes.length}
</p>
</div>
<div>
<Button onClick={() => setNotes("")}>清空笔记</Button>
</div>
</Card>
);
};
useSessionStorageState – 会话存储状态管理
useSessionStorageState
用于将状态同步到 sessionStorage 中。
import React from "react";
import { useSessionStorageState } from "ahooks";
import { Input, Button, Card } from "antd";
const UseSessionStorageStateExample = () => {
const [isLoggedIn, setIsLoggedIn] = useSessionStorageState(
"isLoggedIn",
false
);
return (
<Card title="useSessionStorageState 会话存储状态管理">
<div style={{ marginBottom: 16 }}>
<p>
<strong>登录状态:</strong> {isLoggedIn ? "已登录" : "未登录"}
</p>
</div>
<div>
<Button onClick={() => setIsLoggedIn(true)} style={{ marginRight: 8 }}>
登录
</Button>
<Button onClick={() => setIsLoggedIn(false)} style={{ marginRight: 8 }}>
登出
</Button>
</div>
</Card>
);
};
useDebounce – 防抖状态
useDebounce
用于创建防抖状态,延迟更新值。
import React, { useState } from "react";
import { useDebounce } from "ahooks";
import { Input, Card } from "antd";
const UseDebounceExample = () => {
const [value, setValue] = useState("");
const debouncedValue = useDebounce(value, 500);
return (
<Card title="useDebounce 防抖状态">
<div style={{ marginBottom: 16 }}>
<Input
placeholder="输入内容(500ms 防抖)"
value={value}
onChange={(e) => setValue(e.target.value)}
style={{ marginBottom: 8 }}
/>
<p>
<strong>实时值:</strong> {value}
</p>
<p>
<strong>防抖值:</strong> {debouncedValue}
</p>
</div>
</Card>
);
};
useThrottle – 节流状态
useThrottle
用于创建节流状态,限制更新频率。
import React, { useState } from "react";
import { useThrottle } from "ahooks";
import { Input, Card } from "antd";
const UseThrottleExample = () => {
const [value, setValue] = useState("");
const throttledValue = useThrottle(value, 1000);
return (
<Card title="useThrottle 节流状态">
<div style={{ marginBottom: 16 }}>
<Input
placeholder="输入内容(1000ms 节流)"
value={value}
onChange={(e) => setValue(e.target.value)}
style={{ marginBottom: 8 }}
/>
<p>
<strong>实时值:</strong> {value}
</p>
<p>
<strong>节流值:</strong> {throttledValue}
</p>
</div>
</Card>
);
};
useMap – Map 状态管理
useMap
用于管理 Map 类型的状态。
import React from "react";
import { useMap } from "ahooks";
import { Button, Card, Input } from "antd";
const UseMapExample = () => {
const [map, { set, remove, reset }] = useMap(
new Map([
["name", "张三"],
["age", "25"],
])
);
const [key, setKey] = React.useState("");
const [value, setValue] = React.useState("");
return (
<Card title="useMap Map 状态管理">
<div style={{ marginBottom: 16 }}>
<Input
placeholder="键"
value={key}
onChange={(e) => setKey(e.target.value)}
style={{ marginBottom: 8 }}
/>
<Input
placeholder="值"
value={value}
onChange={(e) => setValue(e.target.value)}
style={{ marginBottom: 8 }}
/>
<p>
<strong>Map 内容:</strong>
</p>
<ul>
{Array.from(map.entries()).map(([k, v]) => (
<li key={k}>
{k}: {v}
</li>
))}
</ul>
</div>
<div>
<Button onClick={() => set(key, value)} style={{ marginRight: 8 }}>
设置
</Button>
<Button onClick={() => remove(key)} style={{ marginRight: 8 }}>
删除
</Button>
<Button onClick={reset}>重置</Button>
</div>
</Card>
);
};
useSet – Set 状态管理
useSet
用于管理 Set 类型的状态。
import React from "react";
import { useSet } from "ahooks";
import { Button, Card, Input } from "antd";
const UseSetExample = () => {
const [set, { add, remove, reset }] = useSet(["apple", "banana"]);
const [value, setValue] = React.useState("");
return (
<Card title="useSet Set 状态管理">
<div style={{ marginBottom: 16 }}>
<Input
placeholder="输入值"
value={value}
onChange={(e) => setValue(e.target.value)}
style={{ marginBottom: 8 }}
/>
<p>
<strong>Set 内容:</strong> {Array.from(set).join(", ")}
</p>
<p>
<strong>包含 {value}:</strong> {set.has(value) ? "是" : "否"}
</p>
</div>
<div>
<Button onClick={() => add(value)} style={{ marginRight: 8 }}>
添加
</Button>
<Button onClick={() => remove(value)} style={{ marginRight: 8 }}>
删除
</Button>
<Button onClick={reset}>重置</Button>
</div>
</Card>
);
};
usePrevious – 获取前一个值
usePrevious
用于获取状态的前一个值。
import React, { useState } from "react";
import { usePrevious } from "ahooks";
import { Button, Card } from "antd";
const UsePreviousExample = () => {
const [count, setCount] = useState(0);
const previousCount = usePrevious(count);
return (
<Card title="usePrevious 获取前一个值">
<div style={{ marginBottom: 16 }}>
<p>
<strong>当前值:</strong> {count}
</p>
<p>
<strong>前一个值:</strong> {previousCount}
</p>
</div>
<div>
<Button onClick={() => setCount(count + 1)} style={{ marginRight: 8 }}>
增加
</Button>
<Button onClick={() => setCount(count - 1)}>减少</Button>
</div>
</Card>
);
};
useRafState – RAF 状态管理
useRafState
用于在 requestAnimationFrame 中更新状态。
import React from "react";
import { useRafState } from "ahooks";
import { Button, Card } from "antd";
const UseRafStateExample = () => {
const [position, setPosition] = useRafState({ x: 0, y: 0 });
const handleMouseMove = (e) => {
setPosition({ x: e.clientX, y: e.clientY });
};
return (
<Card title="useRafState RAF 状态管理">
<div
style={{
height: 200,
border: "1px solid #d9d9d9",
position: "relative",
marginBottom: 16,
}}
onMouseMove={handleMouseMove}
>
<div
style={{
position: "absolute",
left: position.x - 10,
top: position.y - 10,
width: 20,
height: 20,
backgroundColor: "red",
borderRadius: "50%",
}}
/>
<p style={{ position: "absolute", bottom: 0, left: 0 }}>
鼠标位置: ({position.x}, {position.y})
</p>
</div>
</Card>
);
};
useSafeState – 安全状态管理
useSafeState
用于在组件卸载后避免状态更新。
import React from "react";
import { useSafeState } from "ahooks";
import { Button, Card } from "antd";
const UseSafeStateExample = () => {
const [count, setCount] = useSafeState(0);
const handleAsyncUpdate = () => {
setTimeout(() => {
setCount(count + 1);
}, 2000);
};
return (
<Card title="useSafeState 安全状态管理">
<div style={{ marginBottom: 16 }}>
<p>
<strong>计数:</strong> {count}
</p>
<p style={{ fontSize: "12px", color: "#666" }}>
点击按钮后 2 秒更新,如果在更新前组件卸载,不会报错
</p>
</div>
<div>
<Button onClick={() => setCount(count + 1)} style={{ marginRight: 8 }}>
立即更新
</Button>
<Button onClick={handleAsyncUpdate}>异步更新</Button>
</div>
</Card>
);
};
useGetState – 获取状态函数
useGetState
返回一个获取当前状态的函数。
import React from "react";
import { useGetState } from "ahooks";
import { Button, Card } from "antd";
const UseGetStateExample = () => {
const [count, setCount, getCount] = useGetState(0);
const handleLogCount = () => {
console.log("当前计数:", getCount());
};
return (
<Card title="useGetState 获取状态函数">
<div style={{ marginBottom: 16 }}>
<p>
<strong>计数:</strong> {count}
</p>
</div>
<div>
<Button onClick={() => setCount(count + 1)} style={{ marginRight: 8 }}>
增加
</Button>
<Button onClick={handleLogCount}>打印当前值</Button>
</div>
</Card>
);
};
useResetState – 重置状态
useResetState
用于重置状态到初始值。
import React from "react";
import { useResetState } from "ahooks";
import { Button, Card, Input } from "antd";
const UseResetStateExample = () => {
const [name, setName, resetName] = useResetState("张三");
const [age, setAge, resetAge] = useResetState(25);
return (
<Card title="useResetState 重置状态">
<div style={{ marginBottom: 16 }}>
<Input
placeholder="姓名"
value={name}
onChange={(e) => setName(e.target.value)}
style={{ marginBottom: 8 }}
/>
<Input
placeholder="年龄"
value={age}
onChange={(e) => setAge(Number(e.target.value))}
style={{ marginBottom: 8 }}
/>
</div>
<div>
<Button onClick={resetName} style={{ marginRight: 8 }}>
重置姓名
</Button>
<Button onClick={resetAge} style={{ marginRight: 8 }}>
重置年龄
</Button>
<Button
onClick={() => {
resetName();
resetAge();
}}
>
全部重置
</Button>
</div>
</Card>
);
};
状态管理类 hooks 速查表
Hook 名称 | 用途 | 描述 |
---|---|---|
useSetState |
对象状态管理 | 管理对象类型状态,提供类似 setState 的 API |
useBoolean |
布尔值状态管理 | 管理布尔值状态,提供切换方法 |
useToggle |
切换状态管理 | 在两个值之间切换状态 |
useUrlState |
URL 状态管理 | 将状态同步到 URL 参数中 |
useCookieState |
Cookie 状态管理 | 将状态同步到 Cookie 中 |
useLocalStorageState |
本地存储状态管理 | 将状态同步到 localStorage 中 |
useSessionStorageState |
会话存储状态管理 | 将状态同步到 sessionStorage 中 |
useDebounce |
防抖状态 | 创建防抖状态,延迟更新值 |
useThrottle |
节流状态 | 创建节流状态,限制更新频率 |
useMap |
Map 状态管理 | 管理 Map 类型的状态 |
useSet |
Set 状态管理 | 管理 Set 类型的状态 |
usePrevious |
获取前一个值 | 获取状态的前一个值 |
useRafState |
RAF 状态管理 | 在 requestAnimationFrame 中更新状态 |
useSafeState |
安全状态管理 | 在组件卸载后避免状态更新 |
useGetState |
获取状态函数 | 返回一个获取当前状态的函数 |
useResetState |
重置状态 | 重置状态到初始值 |
React强大且灵活hooks库——ahooks入门实践之状态管理类hook(state)详解 - 高质量源码分享平台-免费下载各类网站源码与模板及前沿动态资讯