react

SKILL.md

React

Hooks, functional components, state management, and performance optimization for React apps.

When to Use

Use when:

  • Creating or refactoring React functional components
  • Implementing hooks (useState, useEffect, useMemo, useCallback)
  • Managing state, side effects, or performance optimization
  • Building component composition patterns

Don't use for:

  • Non-React JS (use javascript skill)
  • React Native (use react-native skill)
  • Redux (use redux-toolkit skill)
  • Server-side frameworks (use astro or relevant framework skill)

Critical Patterns

✅ REQUIRED: Functional Components with Hooks

// CORRECT: Functional component with hooks
const Counter: React.FC = () => {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount(count + 1)}>{count}</button>;
};

// WRONG: Class component (legacy)
class Counter extends React.Component {
  state = { count: 0 };
  render() { /* ... */ }
}

✅ REQUIRED: Proper useEffect Dependencies

// CORRECT: All dependencies included
useEffect(() => {
  fetchData(userId);
}, [userId]);

// WRONG: Missing dependencies (stale closures)
useEffect(() => {
  fetchData(userId);
}, []); // userId missing

✅ REQUIRED: Stable Keys for Lists

// CORRECT: Unique IDs
{items.map(item => <li key={item.id}>{item.name}</li>)}

// WRONG: Array index (bugs on reorder/delete)
{items.map((item, index) => <li key={index}>{item.name}</li>)}

❌ NEVER: Conditionally Call Hooks

// WRONG: Breaks React rules
if (condition) {
  const [value, setValue] = useState(0);
}

// CORRECT: Hooks at top level, conditional logic inside
const [value, setValue] = useState(0);
const shouldUse = condition ? value : defaultValue;

Decision Tree

Simple state (<3 values)?
  → useState — see hooks-advanced.md (useState Patterns)

Complex state (4+ related values)?
  → useReducer — see hooks-advanced.md (useReducer Patterns)

Side effect?
  → useEffect with proper deps — see use-effect-patterns.md

Data fetching?
  → useEffect + AbortController — see use-effect-patterns.md (Async Patterns)

Performance issue?
  → Profile first with React DevTools — see performance.md

Expensive computation?
  → useMemo — see performance.md (useMemo)

Callbacks to memoized children?
  → useCallback — see performance.md (useCallback)

Shared state across components?
  → Context API or lift state — see context-patterns.md

Compound component API?
  → see context-patterns.md (Compound Components)

Form with validation?
  → Controlled components — see forms-state.md

Multi-step form?
  → Wizard pattern — see forms-state.md (Multi-Step Forms)

File upload?
  → Controlled input + File API — see forms-state.md (File Uploads)

Large list (1000+)?
  → Virtualization — see performance.md (List Rendering Optimization)

Conditional rendering?
  → && for simple, ternary for if-else, early return for complex logic

Example

import { useState, useMemo } from 'react';

interface TodoProps {
  items: string[];
}

const TodoList: React.FC<TodoProps> = ({ items }) => {
  const [filter, setFilter] = useState('');

  const filteredItems = useMemo(() =>
    items.filter(item => item.toLowerCase().includes(filter.toLowerCase())),
    [items, filter]
  );

  return (
    <div>
      <input value={filter} onChange={(e) => setFilter(e.target.value)} />
      <ul>
        {filteredItems.map((item, index) => (
          <li key={index}>{item}</li>
        ))}
      </ul>
    </div>
  );
};

Edge Cases

Stale closures in useEffect: Include all dependencies or use functional setState: setState(prev => prev + 1).

useEffect cleanup: Return cleanup for subscriptions, timers, listeners to prevent leaks:

useEffect(() => {
  const timer = setInterval(() => {}, 1000);
  return () => clearInterval(timer);
}, []);

Ref vs State: useRef for values that don't trigger re-renders (DOM refs, mutable values). useState for values that update UI.

Batching: React batches setState in event handlers. In async code, use flushSync for immediate updates (rare).

Children prop: Use React.ReactNode type. For render props: {(data) => <Component data={data} />}.

Architecture patterns: Apply Clean Architecture/SOLID only when AGENTS.md specifies it, codebase uses domain/application/infrastructure folders, or user requests. See architecture-patterns SKILL.md.


Checklist

  • Functional components with hooks (no class components)
  • All useEffect dependencies declared
  • Stable keys on list items (unique IDs, not indices)
  • No conditional hook calls
  • Cleanup returned from useEffect for subscriptions/timers
  • useMemo/useCallback only where profiling shows need
  • Controlled inputs for forms with validation
  • Context split by update frequency to avoid unnecessary re-renders

Resources

Weekly Installs
9
GitHub Stars
3
First Seen
Feb 4, 2026
Installed on
cline9
antigravity9
opencode9
mcpjam8
openhands8
zencoder8