| 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. Use when this capability is needed. |
| metadata | {"author":"dungle-scrubs"} |
React Hooks - Patterns & ahooks Library
When working with React/Preact components:
- Identify opportunities for custom hook extraction
- 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
| Need | ahooks Hook | Instead of |
|---|
| Boolean state | useBoolean | useState(false) + toggle fn |
| Toggle between values | useToggle | useState + manual toggle |
| Counter | useCounter | useState(0) + inc/dec fns |
| Object state | useSetState | useState({}) + spread merging |
| Map data | useMap | useState(new Map()) |
| Set data | useSet | useState(new Set()) |
| localStorage | useLocalStorageState | useState + useEffect sync |
| sessionStorage | useSessionStorageState | useState + useEffect sync |
| Cookies | useCookieState | manual cookie handling |
| Debounce value | useDebounce | custom debounce logic |
| Debounce function | useDebounceFn | lodash.debounce wrapper |
| Throttle value | useThrottle | custom throttle logic |
| Throttle function | useThrottleFn | lodash.throttle wrapper |
| Interval | useInterval | setInterval + cleanup |
| Timeout | useTimeout | setTimeout + cleanup |
| Previous value | usePrevious | useRef pattern |
| Mount callback | useMount | useEffect(() => {}, []) |
| Unmount callback | useUnmount | useEffect(() => cleanup, []) |
| Click outside | useClickAway | manual event listener |
| Hover state | useHover | onMouseEnter/Leave handlers |
| Key press | useKeyPress | keyboard event listener |
| Mouse position | useMouse | mousemove listener |
| Scroll position | useScroll | scroll listener |
| Element size | useSize | ResizeObserver |
| In viewport | useInViewport | IntersectionObserver |
| Network status | useNetwork | navigator.onLine + events |
| Document visibility | useDocumentVisibility | visibilitychange event |
| Fullscreen | useFullscreen | Fullscreen API |
| Page title | useTitle | document.title = x |
| Favicon | useFavicon | manual link manipulation |
| Lock async fn | useLockFn | manual loading state |
| Virtual list | useVirtualList | custom virtualization |
| Drag/Drop | useDrag / useDrop | HTML5 drag events |
| Selections | useSelections | manual selection state |
| History travel | useHistoryTravel | undo/redo state |
| Mutation observer | useMutationObserver | MutationObserver API |
| Text selection | useTextSelection | Selection API |
| Responsive | useResponsive | media query listeners |
| Deep compare effect | useDeepCompareEffect | custom deep comparison |
| RAF timing | useRafInterval / useRafTimeout | requestAnimationFrame |
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
-
Repeated useState + useEffect pairs
- Same state + side effect pattern in multiple components
- Example: loading state + fetch logic
-
Complex useEffect with cleanup
- Event listeners, subscriptions, timers
- Example: window resize listener, intersection observer
-
State machines / multi-step state
- Related state variables that change together
- Example: form state (values, errors, touched, submitting)
-
Browser API interactions
- localStorage, sessionStorage, navigator APIs
- Example:
useLocalStorage, useGeolocation
-
Debounced/throttled values
- Any value that needs timing control
- Example: search input, scroll position
-
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
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));
}, []);
}
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() {
{ data, loading, error } = (fetchData);
}
Naming Conventions
- Prefix with
use
- Describe what it manages, not how:
useAuth not useAuthStateAndEffects
- Be specific:
useLocalStorage not useStorage
When Suggesting Hooks
Provide:
- The pattern you spotted
- Suggested hook name
- Brief extraction sketch
- 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
Converted and distributed by TomeVault — claim your Tome and manage your conversions.