Claude
Skills
Sign in
Back

react-patterns

Included with Lifetime
$97 forever

Modern React development with hooks, component patterns, state management, and performance optimization for building scalable applications

Design

What this skill does


# React Patterns - Modern Development Guide

A comprehensive skill for mastering modern React development patterns, including React 18+ features, hooks, component composition, state management strategies, and performance optimization techniques for building scalable web applications.

## When to Use This Skill

Use this skill when:

- Building modern React applications with functional components and hooks
- Implementing complex state management with useReducer and Context API
- Optimizing React application performance with memoization techniques
- Creating reusable custom hooks for shared logic
- Working with Server Components and React Server Components (RSC)
- Managing forms, side effects, and asynchronous operations
- Refactoring class components to modern functional patterns
- Building type-safe React applications with proper patterns
- Implementing advanced component composition patterns
- Debugging React performance issues and unnecessary re-renders

## Core Concepts

### React Philosophy

Modern React emphasizes:

- **Functional Components**: Pure functions that return JSX
- **Hooks**: Composable state and side effect management
- **Declarative UI**: Describe what the UI should look like, React handles updates
- **Component Composition**: Build complex UIs from simple, reusable components
- **Unidirectional Data Flow**: Props flow down, events flow up
- **Immutability**: Never mutate state directly, always create new objects/arrays

### Component Types

1. **Presentational Components**: Focus on UI, receive data via props
2. **Container Components**: Handle logic, state, and side effects
3. **Server Components**: Render on the server, no client JavaScript
4. **Client Components**: Interactive components marked with `"use client"`
5. **Async Components**: Server components that can await data

## React Hooks Reference

### Built-in State Hooks

#### useState

Manage local component state for simple values.

**Syntax:**
```javascript
const [state, setState] = useState(initialValue);
```

**Basic Example:**
```javascript
import { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
      <button onClick={() => setCount(prev => prev + 1)}>Increment (functional)</button>
    </div>
  );
}
```

**Best Practices:**
- Use functional updates when new state depends on previous state
- Keep state as local as possible
- Don't store derived values in state
- Initialize with functions for expensive computations

**Multiple State Variables:**
```javascript
function Form() {
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [age, setAge] = useState(0);

  return (
    <form>
      <input value={name} onChange={e => setName(e.target.value)} />
      <input value={email} onChange={e => setEmail(e.target.value)} />
      <input type="number" value={age} onChange={e => setAge(Number(e.target.value))} />
    </form>
  );
}
```

**Lazy Initialization:**
```javascript
function ExpensiveComponent() {
  // Function only runs once on initial render
  const [state, setState] = useState(() => {
    const initialValue = expensiveComputation();
    return initialValue;
  });

  return <div>{state}</div>;
}
```

#### useReducer

Manage complex state logic with a reducer pattern (similar to Redux).

**Syntax:**
```javascript
const [state, dispatch] = useReducer(reducer, initialState, init?);
```

**Task Manager Example:**
```javascript
import { useReducer } from 'react';

function tasksReducer(tasks, action) {
  switch (action.type) {
    case 'added':
      return [...tasks, {
        id: action.id,
        text: action.text,
        done: false
      }];
    case 'changed':
      return tasks.map(t =>
        t.id === action.task.id ? action.task : t
      );
    case 'deleted':
      return tasks.filter(t => t.id !== action.id);
    default:
      throw Error('Unknown action: ' + action.type);
  }
}

function TaskApp() {
  const [tasks, dispatch] = useReducer(tasksReducer, []);

  function handleAddTask(text) {
    dispatch({
      type: 'added',
      id: Date.now(),
      text: text,
    });
  }

  function handleChangeTask(task) {
    dispatch({
      type: 'changed',
      task: task
    });
  }

  function handleDeleteTask(taskId) {
    dispatch({
      type: 'deleted',
      id: taskId
    });
  }

  return (
    <>
      <AddTask onAddTask={handleAddTask} />
      <TaskList
        tasks={tasks}
        onChangeTask={handleChangeTask}
        onDeleteTask={handleDeleteTask}
      />
    </>
  );
}
```

**When to use useReducer:**
- Multiple related state values
- Complex state update logic
- State transitions follow predictable patterns
- Need to optimize performance with many updates
- Want to separate state logic from component

#### useContext

Access context values without prop drilling.

**Syntax:**
```javascript
const value = useContext(SomeContext);
```

**Theme Context Example:**
```javascript
import { createContext, useContext, useState } from 'react';

const ThemeContext = createContext(null);

export function ThemeProvider({ children }) {
  const [theme, setTheme] = useState('light');

  const toggleTheme = () => {
    setTheme(prev => prev === 'light' ? 'dark' : 'light');
  };

  return (
    <ThemeContext.Provider value={{ theme, toggleTheme }}>
      {children}
    </ThemeContext.Provider>
  );
}

export function useTheme() {
  const context = useContext(ThemeContext);
  if (!context) {
    throw new Error('useTheme must be used within ThemeProvider');
  }
  return context;
}

// Usage
function Button() {
  const { theme, toggleTheme } = useTheme();

  return (
    <button
      onClick={toggleTheme}
      className={theme === 'dark' ? 'btn-dark' : 'btn-light'}
    >
      Toggle Theme
    </button>
  );
}
```

**Combining useReducer + useContext:**
```javascript
import { createContext, useContext, useReducer } from 'react';

const TasksContext = createContext(null);
const TasksDispatchContext = createContext(null);

export function TasksProvider({ children }) {
  const [tasks, dispatch] = useReducer(tasksReducer, initialTasks);

  return (
    <TasksContext.Provider value={tasks}>
      <TasksDispatchContext.Provider value={dispatch}>
        {children}
      </TasksDispatchContext.Provider>
    </TasksContext.Provider>
  );
}

export function useTasks() {
  return useContext(TasksContext);
}

export function useTasksDispatch() {
  return useContext(TasksDispatchContext);
}

// Usage in components
function TaskList() {
  const tasks = useTasks();
  const dispatch = useTasksDispatch();

  return (
    <ul>
      {tasks.map(task => (
        <li key={task.id}>
          {task.text}
          <button onClick={() => dispatch({ type: 'deleted', id: task.id })}>
            Delete
          </button>
        </li>
      ))}
    </ul>
  );
}
```

### Effect Hooks

#### useEffect

Synchronize component with external systems (APIs, DOM, subscriptions).

**Syntax:**
```javascript
useEffect(() => {
  // Effect logic
  return () => {
    // Cleanup logic
  };
}, [dependencies]);
```

**Data Fetching Example:**
```javascript
import { useState, useEffect } from 'react';

function UserProfile({ userId }) {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    let ignore = false; // Prevent race conditions

    async function fetchUser() {
      try {
        setLoading(true);
        const response = await fetch(`/api/users/${userId}`);
        const data = await response.json();

        if (!ignore) {
          setUser(data);
        }
      } catch (err) {
        if (!ignore) {
          setError(err.message);
        }
      } finally {
        if (!ignore) {
          setLoading(false);
        }
      }
    }

    fetchUser();

    return () => {
      ignore = 

Related in Design