AgentSkillsCN

react-hooks

熟练掌握 React Hook 模式,并善用 ahooks 库。在处理 React/Preact 组件时,可借此技能识别 Hook 抽离的潜在机会,并推荐 ahooks 替代方案,取代手动实现的复杂逻辑。

SKILL.md
--- frontmatter
name: react-hooks
description: "React hook patterns and ahooks library usage. Apply when working with React/Preact components to identify hook extraction opportunities and recommend ahooks alternatives to manual implementations."

React Hooks - Patterns & ahooks Library

When working with React/Preact components:

  1. Identify opportunities for custom hook extraction
  2. Always check if ahooks has a hook before writing custom implementations

ahooks - Prefer Over Custom Implementations

ahooks is a high-quality React hooks library. Before writing custom hooks, check if ahooks already provides what you need.

Exclude: useRequest - use TanStack Query instead for data fetching.

Quick Reference by Use Case

Needahooks HookInstead of
Boolean stateuseBooleanuseState(false) + toggle fn
Toggle between valuesuseToggleuseState + manual toggle
CounteruseCounteruseState(0) + inc/dec fns
Object stateuseSetStateuseState({}) + spread merging
Map datauseMapuseState(new Map())
Set datauseSetuseState(new Set())
localStorageuseLocalStorageStateuseState + useEffect sync
sessionStorageuseSessionStorageStateuseState + useEffect sync
CookiesuseCookieStatemanual cookie handling
Debounce valueuseDebouncecustom debounce logic
Debounce functionuseDebounceFnlodash.debounce wrapper
Throttle valueuseThrottlecustom throttle logic
Throttle functionuseThrottleFnlodash.throttle wrapper
IntervaluseIntervalsetInterval + cleanup
TimeoutuseTimeoutsetTimeout + cleanup
Previous valueusePrevioususeRef pattern
Mount callbackuseMountuseEffect(() => {}, [])
Unmount callbackuseUnmountuseEffect(() => cleanup, [])
Click outsideuseClickAwaymanual event listener
Hover stateuseHoveronMouseEnter/Leave handlers
Key pressuseKeyPresskeyboard event listener
Mouse positionuseMousemousemove listener
Scroll positionuseScrollscroll listener
Element sizeuseSizeResizeObserver
In viewportuseInViewportIntersectionObserver
Network statususeNetworknavigator.onLine + events
Document visibilityuseDocumentVisibilityvisibilitychange event
FullscreenuseFullscreenFullscreen API
Page titleuseTitledocument.title = x
FaviconuseFaviconmanual link manipulation
Lock async fnuseLockFnmanual loading state
Virtual listuseVirtualListcustom virtualization
Drag/DropuseDrag / useDropHTML5 drag events
SelectionsuseSelectionsmanual selection state
History traveluseHistoryTravelundo/redo state
Mutation observeruseMutationObserverMutationObserver API
Text selectionuseTextSelectionSelection API
ResponsiveuseResponsivemedia query listeners
Deep compare effectuseDeepCompareEffectcustom deep comparison
RAF timinguseRafInterval / useRafTimeoutrequestAnimationFrame

Detailed hook documentation: $file: ./ahooks/index.md

When to Apply

  • Reviewing React/Preact component code
  • Creating new components with stateful logic
  • Editing existing components
  • Code review discussions about React patterns

Hook Extraction Signals

Strong Candidates for Custom Hooks

  1. Repeated useState + useEffect pairs

    • Same state + side effect pattern in multiple components
    • Example: loading state + fetch logic
  2. Complex useEffect with cleanup

    • Event listeners, subscriptions, timers
    • Example: window resize listener, intersection observer
  3. State machines / multi-step state

    • Related state variables that change together
    • Example: form state (values, errors, touched, submitting)
  4. Browser API interactions

    • localStorage, sessionStorage, navigator APIs
    • Example: useLocalStorage, useGeolocation
  5. Debounced/throttled values

    • Any value that needs timing control
    • Example: search input, scroll position
  6. Media queries / responsive logic

    • Breakpoint detection, orientation changes
    • Example: useMediaQuery, useBreakpoint

Weak Candidates (Usually Keep Inline)

  • Single useState with simple updates
  • useEffect that only runs once on mount with no cleanup
  • Component-specific logic unlikely to be reused

Extraction Pattern

tsx
// Before: Logic scattered in component
function Component() {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    fetchData().then(setData).catch(setError).finally(() => setLoading(false));
  }, []);

  // ... render
}

// After: Extracted to custom hook
function useAsyncData(fetchFn) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    fetchFn().then(setData).catch(setError).finally(() => setLoading(false));
  }, [fetchFn]);

  return { data, loading, error };
}

function Component() {
  const { data, loading, error } = useAsyncData(fetchData);
  // ... render
}

Naming Conventions

  • Prefix with use
  • Describe what it manages, not how: useAuth not useAuthStateAndEffects
  • Be specific: useLocalStorage not useStorage

When Suggesting Hooks

Provide:

  1. The pattern you spotted
  2. Suggested hook name
  3. Brief extraction sketch
  4. Reuse potential (how many places could use this?)

Don't:

  • Suggest hooks for trivial single-use logic
  • Over-abstract stable, simple code
  • Force extraction when inline is clearer