用途
ahooks-v3 技能用于指导在 React 应用中使用 ahooks v3+ 的实用 Hooks 进行状态管理,重点覆盖两类场景:分组状态更新与 localStorage 持久化。它不覆盖数据获取、URL 状态管理、复杂状态机与异步操作。
适用范围与前提
- 适用:ahooks v3+ 的实用 Hooks,用于 React 状态管理、分组状态更新、localStorage 持久化。
- 不覆盖:数据获取(应使用 TanStack Query)、URL 状态管理(应使用 nuqs)、复杂状态机、异步操作。
- 前提假设:ahooks v3+;React 18+ 且支持 Hooks;TypeScript v5+(用于类型推断);仅限客户端(Hooks 依赖浏览器 API 才能使用 localStorage)。
主要能力与原则
- 使用 useSetState 管理会一起变化的分组状态(不用于 URL 可共享场景)。
- 使用 useLocalStorageState 实现跨浏览器会话的持久化状态。
- URL 可共享状态优先使用 nuqs,而非 localStorage。
- 异步操作与加载状态优先使用 TanStack Query。
- 仅在简单独立状态时使用 useState(较少使用)。
使用方式
useSetState 模式
用于一起更新的分组状态:
import { useSetState } from 'ahooks'
const [state, setState] = useSetState({
name: '',
email: '',
age: 0,
})
// 部分更新(浅合并)
setState({ name: 'John' })
setState(prev => ({ ...prev, email: 'john@example.com' }))
适用:表单状态、游戏引擎状态、会一起变化的 UI 状态(若不可 URL 共享)。 不适用:URL 可共享状态(用 nuqs)、加载状态(用 TanStack Query)。
useLocalStorageState 模式
用于跨浏览器会话持久化的状态:
import { useLocalStorageState } from 'ahooks'
const [value, setValue] = useLocalStorageState<boolean>('key', {
defaultValue: false,
})
// 使用泛型实现类型安全
const [settings, setSettings] = useLocalStorageState<Settings>('settings', {
defaultValue: { theme: 'light', fontSize: 14 },
})
适用:用户偏好、调试标志、应跨会话保留的设置。 不适用:URL 可共享状态(用 nuqs)、敏感数据(应使用安全存储)。
与 nuqs 集成
在 URL 与 localStorage 之间双向同步:
import { useLocalStorageState } from 'ahooks'
import { useQueryState } from 'nuqs'
import { useEffect, useRef } from 'react'
const [queryState, setQueryState] = useQueryState('debug')
const [storageState, setStorageState] = useLocalStorageState<boolean>('debug', {
defaultValue: false,
})
const isFirstMount = useRef(true)
// 挂载时同步:localStorage → URL
useEffect(() => {
if (isFirstMount.current) {
isFirstMount.current = false
if (storageState && queryState !== 'true') {
setQueryState('true')
return
}
}
// 变更同步:URL → localStorage
if (queryState === 'true' && !storageState) {
setStorageState(true)
} else if (queryState === 'false' && storageState) {
setStorageState(false)
}
}, [queryState, storageState, setQueryState, setStorageState])
用例:调试标志、功能开关,既需要 URL 可共享又需要持久化。
约束
必须:
- 对不在 URL 中的分组状态(表单状态、游戏引擎状态、临时 UI 状态)使用 useSetState。
- 使用 useLocalStorageState 实现 localStorage 持久化。
应当:
- URL 可共享状态优先使用 nuqs,而非 localStorage。
- 异步操作与加载状态优先使用 TanStack Query。
- 使用 TypeScript 泛型实现类型安全状态:
useLocalStorageState<boolean>('key', { defaultValue: false })。
避免:
- 用于 URL 状态(改用 nuqs)。
- 用于加载/错误状态(改用 TanStack Query)。
- 用于复杂异步操作(改用 TanStack Query)。
- 在没有显式同步逻辑的情况下混用 URL 状态与 localStorage。
适用场景
- 表单状态、游戏引擎状态、会一起变化的临时 UI 状态(不可 URL 共享)。
- 用户偏好、调试标志、应跨会话保留的设置。
- 需要同时 URL 可共享且持久化的调试标志与功能开关(配合 nuqs 双向同步)。
限制
- 仅限客户端使用,Hooks 依赖浏览器 API 才能使用 localStorage。
- 不覆盖数据获取、URL 状态管理、复杂状态机与异步操作。
- 敏感数据不应使用 localStorage,应使用安全存储。
- 混用 URL 状态与 localStorage 时必须编写显式同步逻辑。
状态管理决策树
- URL 可共享状态 → 使用 nuqs(过滤器、搜索、标签页、分页)。
- 不在 URL 中的分组状态 → 使用 useSetState(表单状态、游戏引擎、临时 UI)。
- 异步操作 → 使用 TanStack Query(数据获取、变更、缓存)。
- localStorage 持久化 → 使用 useLocalStorageState(偏好、设置)。
- 简单独立状态 → 使用 useState(较少使用,优先考虑其他选项)。
交互关系
- 与 nuqs-v2 互补,用于 URL 状态管理(可双向同步)。
- 与 TanStack Query 互补,用于异步操作(数据获取使用 TanStack Query)。
- 属于状态管理决策树的一部分(参见 React 规则)。
- 与 React 18+ Hooks 架构配合使用。