# React

> Modern React with hooks and functional components. Trigger: When creating components, implementing hooks, managing state, or optimizing.

- Skill: `joabgonzalez/react` (Agent Skill, multi-file: 11 files)
- Install (CLI): `npx skillmds@latest add joabgonzalez/react`
- Raw SKILL.md: https://api.skillmd.com/api/skills/joabgonzalez/react/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- License: Apache 2.0
- Author: joabgonzalez (https://skillmd.com/u/joabgonzalez)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/joabgonzalez/react

---


# 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

```typescript
// 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

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

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

### ✅ REQUIRED: Stable Keys for Lists

```typescript
// 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

```typescript
// 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

```typescript
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:

```typescript
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](../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

- [references/](references/README.md) -- hooks-advanced, use-effect-patterns, performance, context-patterns, forms-state
- https://react.dev/
- https://react.dev/reference/react

