home / skills / hoangnguyen0403 / agent-skills-standard / hooks

hooks skill

/skills/react/hooks

This skill helps you optimize React hooks usage and performance by enforcing exhaustive dependencies, memoization, and clean architectural patterns.

npx playbooks add skill hoangnguyen0403/agent-skills-standard --skill hooks

Review the files below or copy the command above to add this skill to your agents.

Files (2)
SKILL.md
2.1 KB
---
name: React Hooks Expert
description: Standards for efficient React functional components and hooks usage.
metadata:
  labels: [react, hooks, performance, frontend]
  triggers:
    files: ['**/*.tsx', '**/*.jsx']
    keywords: [useEffect, useCallback, useMemo, useState]
---

# React Hooks Expert

## **Priority: P0 (CRITICAL)**

**You are a React Performance Expert.** Optimize renders and prevent memory leaks.

## Implementation Guidelines

- **Dependency Arrays**: exhaustive-deps is Law. Never suppress it.
- **Memoization**: `useMemo` for heavy calc, `useCallback` for props.
- **Custom Hooks**: Extract logic starting with `use...`.
- **State**: Keep local state minimal; lift up strictly when needed.
- **Rules**: Top-level only. Only in React functions.
- **`useEffect`**: Sync with external systems ONLY. Cleanup required.
- **`useRef`**: Mutable state without re-renders (DOM, timers, tracking).
- **`useMemo`/`Callback`**: Measure first. Use for stable refs or heavy computation.
- **Dependencies**: Exhaustive deps always. Fix logic, don't disable linter.
- **Custom Hooks**: Extract shared logic. Prefix `use*`.
- **Refs as Escape Hatch**: Access imperative APIs (focus, scroll).
- **Stability**: Use `useLatest` pattern (ref) for event handlers to avoid dependency changes.
- **Concurrency**: `useTransition` / `useDeferredValue` for non-blocking UI updates.
- **Initialization**: Lazy state `useState(() => expensive())`.

## Performance Checklist (Mandatory)

- [ ] **Rules of Hooks**: Called at top level? No loops/conditions?
- [ ] **Dependencies**: Are objects/arrays memoized before passing to deps?
- [ ] **Cleanup**: Do `useEffect` subscriptions return cleanup functions?
- [ ] **Render Count**: Does component re-render excessively?

## Anti-Patterns

- **No Missing Deps**: Fix logic, don't disable linter.
- **No Complex Effects**: Break tailored effects into smaller ones.
- **No Derived State**: Compute during render, don't `useEffect` to sync state.
- **No Heavy Init**: Use lazy state initialization `useState(() => heavy())`.

## References

- [Optimization Patterns](references/REFERENCE.md)

Overview

This skill codifies standards for efficient React functional components and hooks usage. It focuses on render optimization, correct dependency management, and preventing memory leaks. The guidance is practical, enforceable, and geared toward predictable, high-performance UI code.

How this skill works

It inspects hook usage patterns, dependency arrays, memoization, and effect cleanup to identify performance and correctness issues. It enforces exhaustive dependencies, recommends when to memoize values or callbacks, and flags anti-patterns like derived state, heavy initialization in render, or missing effect cleanup. The output highlights fixes: extract custom hooks, memoize inputs, or convert effects into smaller, deterministic units.

When to use it

  • When building or reviewing functional React components for performance
  • During code reviews to enforce hooks best practices and prevent regressions
  • When diagnosing excessive re-renders or memory leaks
  • When introducing complex effects, timers, or subscriptions
  • When aiming to keep local state minimal and predictable

Best practices

  • Treat exhaustive-deps as law: always include real dependencies and fix logic rather than silencing the linter
  • Measure before memoizing; use useMemo for heavy calculations and useCallback for stable callback references
  • Extract shared or complex logic into custom hooks prefixed with use* and keep hooks at top level of components
  • Keep local state minimal; compute derived values in render instead of syncing via effects
  • Always return cleanup from useEffect for subscriptions, timers, and external listeners
  • Use refs (useRef/useLatest) as an escape hatch for mutable data that shouldn’t trigger renders

Example use cases

  • Convert repeated effect logic into a custom usePolling or useSubscription hook with proper cleanup
  • Fix a component that re-renders excessively by memoizing prop objects and callbacks before passing them downstream
  • Replace derived state synced in useEffect with direct render-time computation to eliminate stale updates
  • Use lazy initialization useState(() => expensiveInit()) for expensive startup work
  • Apply useTransition or useDeferredValue to keep UI responsive during large list updates

FAQ

Can I ever disable exhaustive-deps?

No. Don’t disable it. Fix the logic by memoizing values or restructuring effects so dependencies are correct.

When should I prefer useMemo over useRef?

Use useMemo for expensive computed values that should be recalculated only when inputs change. Use useRef for mutable, imperative state that must not trigger re-renders.

How do I avoid stale closures in event handlers?

Use a stable ref pattern (useLatest) to hold the latest value, or memoize handlers with correct dependencies so closures always see up-to-date values.