Skip to main content

Command Palette

Search for a command to run...

React.js Complete Reference Guide

Published
20 min readView as Markdown
# React.js Complete Reference Guide

A comprehensive cheat sheet covering everything you need to know about React - from basic components to advanced hooks, with best practices and common patterns. Perfect for beginners and experienced developers.

---

## Table of Contents

1. [Getting Started](#getting-started)
2. [Components](#components)
3. [Props](#props)
4. [State Management](#state-management)
5. [Lifecycle Methods](#lifecycle-methods)
6. [Hooks](#hooks)
7. [Event Handling](#event-handling)
8. [Conditional Rendering](#conditional-rendering)
9. [Lists and Keys](#lists-and-keys)
10. [Forms](#forms)
11. [Context API](#context-api)
12. [Refs](#refs)
13. [Error Boundaries](#error-boundaries)
14. [Performance Optimization](#performance-optimization)
15. [Advanced Patterns](#advanced-patterns)
16. [Best Practices](#best-practices)

---

## Getting Started

### Installation

```bash
# Create new Next.js project (recommended)
npx create-next-app@latest my-app

# Or Create React App
npx create-react-app my-app

# Or with Vite (faster)
npm create vite@latest my-app -- --template react

# Navigate and install
cd my-app
npm install
npm start
```

### Basic Setup

```jsx
import React from 'react';
import ReactDOM from 'react-dom/client';

function App() {
  return <h1>Hello React!</h1>;
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
```

---

## Components

### Functional Components (Modern)

```jsx
// Simple functional component
function Greeting() {
  return <h1>Hello World!</h1>;
}

// With props
function Greeting({ name }) {
  return <h1>Hello {name}!</h1>;
}

// Arrow function syntax
const Greeting = ({ name }) => {
  return <h1>Hello {name}!</h1>;
};

// Implicit return (concise)
const Greeting = ({ name }) => <h1>Hello {name}!</h1>;
```

### Class Components (Legacy)

```jsx
import React, { Component } from 'react';

class Hello extends Component {
  render() {
    return (
      <div className='message-box'>
        Hello {this.props.name}
      </div>
    );
  }
}
```

### Component Composition

```jsx
function Welcome() {
  return (
    <div>
      <Header />
      <MainContent />
      <Footer />
    </div>
  );
}
```

### Fragments

```jsx
import React, { Fragment } from 'react';

// Using Fragment
function UserInfo() {
  return (
    <Fragment>
      <UserAvatar />
      <UserProfile />
    </Fragment>
  );
}

// Short syntax
function UserInfo() {
  return (
    <>
      <UserAvatar />
      <UserProfile />
    </>
  );
}
```

---

## Props

### Passing Props

```jsx
<Video 
  fullscreen={true} 
  autoplay={false}
  title="My Video"
/>
```

### Receiving Props

```jsx
// Functional component
function Video({ fullscreen, autoplay, title }) {
  return <div>{title}</div>;
}

// Class component
class Video extends Component {
  render() {
    const { fullscreen, autoplay, title } = this.props;
    return <div>{title}</div>;
  }
}
```

### Default Props

```jsx
// Functional component
function Button({ color = 'blue', size = 'medium' }) {
  return <button className={`btn-${color} btn-${size}`}>Click</button>;
}

// Class component
class Button extends Component {
  static defaultProps = {
    color: 'blue',
    size: 'medium'
  };

  render() {
    return <button>Click</button>;
  }
}
```

### Children Props

```jsx
function AlertBox({ children }) {
  return (
    <div className='alert-box'>
      {children}
    </div>
  );
}

// Usage
<AlertBox>
  <h1>Warning!</h1>
  <p>You have pending notifications</p>
</AlertBox>
```

### Spread Props

```jsx
function VideoPlayer(props) {
  return <VideoEmbed {...props} />;
}
```

---

## State Management

### useState Hook (Functional Components)

```jsx
import React, { 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(0)}>
        Reset
      </button>
    </div>
  );
}
```

### Multiple State Variables

```jsx
function UserProfile() {
  const [age, setAge] = useState(25);
  const [name, setName] = useState('John');
  const [todos, setTodos] = useState([]);

  return <div>User: {name}, Age: {age}</div>;
}
```

### State with Objects

```jsx
function Form() {
  const [formData, setFormData] = useState({
    username: '',
    email: '',
    age: 0
  });

  const handleChange = (e) => {
    setFormData({
      ...formData,
      [e.target.name]: e.target.value
    });
  };

  return (
    <form>
      <input 
        name="username" 
        value={formData.username}
        onChange={handleChange} 
      />
    </form>
  );
}
```

### State with Arrays

```jsx
function TodoList() {
  const [todos, setTodos] = useState(['Task 1', 'Task 2']);

  // Add item
  const addTodo = (newTodo) => {
    setTodos([...todos, newTodo]);
  };

  // Remove item
  const removeTodo = (index) => {
    setTodos(todos.filter((_, i) => i !== index));
  };

  // Update item
  const updateTodo = (index, newValue) => {
    const newTodos = [...todos];
    newTodos[index] = newValue;
    setTodos(newTodos);
  };

  return <div>{/* Render todos */}</div>;
}
```

### Functional Updates

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

  // When new state depends on previous state
  const increment = () => {
    setCount(prevCount => prevCount + 1);
  };

  return <button onClick={increment}>Count: {count}</button>;
}
```

### Class Component State (Legacy)

```jsx
class Counter extends Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
  }

  // Or with class fields
  state = { count: 0 };

  increment = () => {
    this.setState({ count: this.state.count + 1 });

    // Or functional form
    this.setState(prevState => ({ 
      count: prevState.count + 1 
    }));
  };

  render() {
    return (
      <button onClick={this.increment}>
        Count: {this.state.count}
      </button>
    );
  }
}
```

---

## Lifecycle Methods

### Class Component Lifecycle

```jsx
class MyComponent extends Component {
  // 1. Mounting
  constructor(props) {
    super(props);
    this.state = { data: null };
  }

  // 2. After component mounts (DOM available)
  componentDidMount() {
    // Fetch data, add event listeners, timers
    fetch('/api/data')
      .then(res => res.json())
      .then(data => this.setState({ data }));
  }

  // 3. Before component re-renders
  shouldComponentUpdate(nextProps, nextState) {
    // Return false to skip render (optimization)
    return true;
  }

  // 4. After component updates
  componentDidUpdate(prevProps, prevState) {
    // Respond to prop/state changes
    if (prevProps.userId !== this.props.userId) {
      this.fetchUserData(this.props.userId);
    }
  }

  // 5. Before component unmounts
  componentWillUnmount() {
    // Cleanup: remove event listeners, cancel timers
    clearInterval(this.timerId);
  }

  // 6. Error handling
  componentDidCatch(error, info) {
    console.error('Error:', error);
    this.setState({ hasError: true });
  }

  render() {
    return <div>{this.state.data}</div>;
  }
}
```

### Lifecycle Chart

| Phase | Method | Purpose |
|-------|--------|---------|
| **Mounting** | `constructor()` | Initialize state |
| | `render()` | Return JSX |
| | `componentDidMount()` | API calls, subscriptions |
| **Updating** | `shouldComponentUpdate()` | Performance optimization |
| | `render()` | Re-render component |
| | `componentDidUpdate()` | Post-update operations |
| **Unmounting** | `componentWillUnmount()` | Cleanup |
| **Error** | `componentDidCatch()` | Error handling |

---

## Hooks

### useState - State Management

```jsx
import { useState } from 'react';

function Example() {
  const [count, setCount] = useState(0);
  const [text, setText] = useState('');
  const [items, setItems] = useState([]);

  return <div>Count: {count}</div>;
}
```

### useEffect - Side Effects

```jsx
import { useState, useEffect } from 'react';

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

  // Runs after every render
  useEffect(() => {
    document.title = `Count: ${count}`;
  });

  // Runs only once (on mount)
  useEffect(() => {
    console.log('Component mounted');
  }, []);

  // Runs when dependencies change
  useEffect(() => {
    console.log('Count changed:', count);
  }, [count]);

  // With cleanup
  useEffect(() => {
    const timer = setInterval(() => {
      console.log('Tick');
    }, 1000);

    return () => {
      clearInterval(timer); // Cleanup
    };
  }, []);

  return <div>Count: {count}</div>;
}
```

### useEffect Patterns

```jsx
// Fetch data on mount
useEffect(() => {
  async function fetchData() {
    const response = await fetch('/api/data');
    const data = await response.json();
    setData(data);
  }
  fetchData();
}, []);

// Subscribe/Unsubscribe
useEffect(() => {
  const subscription = DataSource.subscribe(handleChange);
  return () => {
    subscription.unsubscribe();
  };
}, []);

// Event listeners
useEffect(() => {
  const handleResize = () => {
    setWindowWidth(window.innerWidth);
  };

  window.addEventListener('resize', handleResize);
  return () => window.removeEventListener('resize', handleResize);
}, []);
```

### useContext - Consume Context

```jsx
import { useContext } from 'react';
import { ThemeContext } from './ThemeContext';

function ThemedButton() {
  const { theme, toggleTheme } = useContext(ThemeContext);

  return (
    <button 
      onClick={toggleTheme}
      style={{ background: theme === 'dark' ? '#333' : '#fff' }}
    >
      Current theme: {theme}
    </button>
  );
}
```

### useReducer - Complex State Logic

```jsx
import { useReducer } from 'react';

// Reducer function
function counterReducer(state, action) {
  switch (action.type) {
    case 'increment':
      return { count: state.count + 1 };
    case 'decrement':
      return { count: state.count - 1 };
    case 'reset':
      return { count: 0 };
    default:
      throw new Error('Unknown action');
  }
}

function Counter() {
  const [state, dispatch] = useReducer(counterReducer, { count: 0 });

  return (
    <div>
      <p>Count: {state.count}</p>
      <button onClick={() => dispatch({ type: 'increment' })}>+</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
      <button onClick={() => dispatch({ type: 'reset' })}>Reset</button>
    </div>
  );
}
```

### useRef - DOM References & Persistent Values

```jsx
import { useRef, useEffect } from 'react';

function TextInput() {
  const inputRef = useRef(null);
  const renderCount = useRef(0);

  useEffect(() => {
    // Focus input on mount
    inputRef.current.focus();

    // Track renders (doesn't cause re-render)
    renderCount.current += 1;
  });

  return (
    <div>
      <input ref={inputRef} type="text" />
      <p>Renders: {renderCount.current}</p>
    </div>
  );
}
```

### useMemo - Memoize Expensive Calculations

```jsx
import { useMemo, useState } from 'react';

function ExpensiveComponent({ items }) {
  const [filter, setFilter] = useState('');

  // Only recalculates when items or filter changes
  const filteredItems = useMemo(() => {
    console.log('Filtering items...');
    return items.filter(item => 
      item.name.toLowerCase().includes(filter.toLowerCase())
    );
  }, [items, filter]);

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

### useCallback - Memoize Functions

```jsx
import { useCallback, useState } from 'react';

function Parent() {
  const [count, setCount] = useState(0);
  const [otherState, setOtherState] = useState(0);

  // Function is recreated only when count changes
  const handleClick = useCallback(() => {
    console.log('Count:', count);
  }, [count]);

  return (
    <div>
      <ChildComponent onClick={handleClick} />
      <button onClick={() => setOtherState(otherState + 1)}>
        Update Other State
      </button>
    </div>
  );
}
```

### useLayoutEffect - Synchronous Effects

```jsx
import { useLayoutEffect, useRef, useState } from 'react';

function Tooltip() {
  const ref = useRef(null);
  const [position, setPosition] = useState({ top: 0, left: 0 });

  // Fires synchronously before browser paint
  useLayoutEffect(() => {
    const rect = ref.current.getBoundingClientRect();
    setPosition({
      top: rect.bottom,
      left: rect.left
    });
  }, []);

  return <div ref={ref}>Hover me</div>;
}
```

### useImperativeHandle - Customize Ref Exposure

```jsx
import { forwardRef, useImperativeHandle, useRef } from 'react';

const FancyInput = forwardRef((props, ref) => {
  const inputRef = useRef();

  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus();
    },
    clear: () => {
      inputRef.current.value = '';
    }
  }));

  return <input ref={inputRef} />;
});

// Usage
function Parent() {
  const fancyInputRef = useRef();

  return (
    <>
      <FancyInput ref={fancyInputRef} />
      <button onClick={() => fancyInputRef.current.focus()}>
        Focus Input
      </button>
    </>
  );
}
```

### Custom Hooks

```jsx
// Custom hook for window size
function useWindowSize() {
  const [size, setSize] = useState({
    width: window.innerWidth,
    height: window.innerHeight
  });

  useEffect(() => {
    const handleResize = () => {
      setSize({
        width: window.innerWidth,
        height: window.innerHeight
      });
    };

    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, []);

  return size;
}

// Usage
function App() {
  const { width, height } = useWindowSize();
  return <div>Window: {width} x {height}</div>;
}
```

```jsx
// Custom hook for fetching data
function useFetch(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    async function fetchData() {
      try {
        setLoading(true);
        const response = await fetch(url);
        const json = await response.json();
        setData(json);
      } catch (err) {
        setError(err);
      } finally {
        setLoading(false);
      }
    }

    fetchData();
  }, [url]);

  return { data, loading, error };
}

// Usage
function UserProfile({ userId }) {
  const { data, loading, error } = useFetch(`/api/users/${userId}`);

  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;
  return <div>{data.name}</div>;
}
```

---

## Event Handling

### Handling Events

```jsx
function Button() {
  const handleClick = (e) => {
    e.preventDefault();
    console.log('Button clicked!');
  };

  return <button onClick={handleClick}>Click Me</button>;
}
```

### Common Events

```jsx
function EventExamples() {
  return (
    <div>
      {/* Click events */}
      <button onClick={() => console.log('Clicked')}>Click</button>
      <button onDoubleClick={() => console.log('Double clicked')}>
        Double Click
      </button>

      {/* Form events */}
      <input 
        onChange={(e) => console.log(e.target.value)}
        onFocus={() => console.log('Focused')}
        onBlur={() => console.log('Blurred')}
      />

      {/* Keyboard events */}
      <input 
        onKeyDown={(e) => console.log('Key down:', e.key)}
        onKeyUp={(e) => console.log('Key up:', e.key)}
        onKeyPress={(e) => console.log('Key press:', e.key)}
      />

      {/* Mouse events */}
      <div
        onMouseEnter={() => console.log('Mouse entered')}
        onMouseLeave={() => console.log('Mouse left')}
        onMouseMove={(e) => console.log(e.clientX, e.clientY)}
      >
        Hover me
      </div>
    </div>
  );
}
```

### Event with Parameters

```jsx
function TodoList() {
  const [todos, setTodos] = useState(['Task 1', 'Task 2']);

  const handleDelete = (index) => {
    setTodos(todos.filter((_, i) => i !== index));
  };

  return (
    <ul>
      {todos.map((todo, index) => (
        <li key={index}>
          {todo}
          <button onClick={() => handleDelete(index)}>Delete</button>
        </li>
      ))}
    </ul>
  );
}
```

---

## Conditional Rendering

### Using If-Else

```jsx
function Greeting({ isLoggedIn }) {
  if (isLoggedIn) {
    return <h1>Welcome back!</h1>;
  }
  return <h1>Please sign in.</h1>;
}
```

### Ternary Operator

```jsx
function Greeting({ isLoggedIn }) {
  return (
    <div>
      {isLoggedIn ? <h1>Welcome back!</h1> : <h1>Please sign in.</h1>}
    </div>
  );
}
```

### Logical && Operator

```jsx
function Mailbox({ unreadMessages }) {
  return (
    <div>
      <h1>Hello!</h1>
      {unreadMessages.length > 0 && (
        <h2>You have {unreadMessages.length} unread messages.</h2>
      )}
    </div>
  );
}
```

### Switch Statement

```jsx
function NotificationBadge({ type }) {
  const renderBadge = () => {
    switch(type) {
      case 'success':
        return <span className="badge-success">✓</span>;
      case 'error':
        return <span className="badge-error">✗</span>;
      case 'warning':
        return <span className="badge-warning">!</span>;
      default:
        return null;
    }
  };

  return <div>{renderBadge()}</div>;
}
```

### Null Rendering

```jsx
function Warning({ showWarning }) {
  if (!showWarning) {
    return null;
  }

  return <div className="warning">Warning!</div>;
}
```

---

## Lists and Keys

### Rendering Lists

```jsx
function TodoList() {
  const todos = [
    { id: 1, text: 'Learn React' },
    { id: 2, text: 'Build an app' },
    { id: 3, text: 'Deploy it' }
  ];

  return (
    <ul>
      {todos.map(todo => (
        <li key={todo.id}>{todo.text}</li>
      ))}
    </ul>
  );
}
```

### Keys Best Practices

```jsx
// ✅ Good: Using unique IDs
{items.map(item => (
  <div key={item.id}>{item.name}</div>
))}

// ❌ Bad: Using index as key (when order may change)
{items.map((item, index) => (
  <div key={index}>{item.name}</div>
))}

// ✅ Acceptable: Using index when list is static
{staticItems.map((item, index) => (
  <div key={index}>{item}</div>
))}
```

### Extracting Components with Keys

```jsx
function TodoItem({ todo }) {
  return <li>{todo.text}</li>;
}

function TodoList({ todos }) {
  return (
    <ul>
      {todos.map(todo => (
        <TodoItem key={todo.id} todo={todo} />
      ))}
    </ul>
  );
}
```

---

## Forms

### Controlled Components

```jsx
function LoginForm() {
  const [formData, setFormData] = useState({
    username: '',
    password: ''
  });

  const handleChange = (e) => {
    const { name, value } = e.target;
    setFormData(prev => ({
      ...prev,
      [name]: value
    }));
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log('Submitted:', formData);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        name="username"
        value={formData.username}
        onChange={handleChange}
        placeholder="Username"
      />
      <input
        type="password"
        name="password"
        value={formData.password}
        onChange={handleChange}
        placeholder="Password"
      />
      <button type="submit">Login</button>
    </form>
  );
}
```

### Form Elements

```jsx
function FormElements() {
  const [text, setText] = useState('');
  const [checked, setChecked] = useState(false);
  const [selected, setSelected] = useState('option1');

  return (
    <form>
      {/* Text input */}
      <input
        type="text"
        value={text}
        onChange={e => setText(e.target.value)}
      />

      {/* Checkbox */}
      <input
        type="checkbox"
        checked={checked}
        onChange={e => setChecked(e.target.checked)}
      />

      {/* Select */}
      <select value={selected} onChange={e => setSelected(e.target.value)}>
        <option value="option1">Option 1</option>
        <option value="option2">Option 2</option>
      </select>

      {/* Textarea */}
      <textarea
        value={text}
        onChange={e => setText(e.target.value)}
      />

      {/* Radio buttons */}
      <input
        type="radio"
        name="choice"
        value="a"
        checked={selected === 'a'}
        onChange={e => setSelected(e.target.value)}
      />
    </form>
  );
}
```

### Uncontrolled Components with Refs

```jsx
function UncontrolledForm() {
  const inputRef = useRef();

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log('Input value:', inputRef.current.value);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input ref={inputRef} type="text" defaultValue="Initial" />
      <button type="submit">Submit</button>
    </form>
  );
}
```

---

## Context API

### Creating Context

```jsx
import { createContext, useState, useContext } from 'react';

// Create context
const ThemeContext = createContext();

// Provider component
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>
  );
}

// Consumer component
function ThemedButton() {
  const { theme, toggleTheme } = useContext(ThemeContext);

  return (
    <button 
      onClick={toggleTheme}
      style={{
        background: theme === 'dark' ? '#333' : '#fff',
        color: theme === 'dark' ? '#fff' : '#333'
      }}
    >
      Current: {theme}
    </button>
  );
}

// App structure
function App() {
  return (
    <ThemeProvider>
      <ThemedButton />
    </ThemeProvider>
  );
}
```

### Multiple Contexts

```jsx
const UserContext = createContext();
const ThemeContext = createContext();

function App() {
  return (
    <UserContext.Provider value={user}>
      <ThemeContext.Provider value={theme}>
        <MainApp />
      </ThemeContext.Provider>
    </UserContext.Provider>
  );
}

function MainApp() {
  const user = useContext(UserContext);
  const theme = useContext(ThemeContext);

  return <div>{user.name} - {theme}</div>;
}
```

---

## Refs

### DOM References

```jsx
function TextInput() {
  const inputRef = useRef(null);

  const focusInput = () => {
    inputRef.current.focus();
  };

  return (
    <>
      <input ref={inputRef} type="text" />
      <button onClick={focusInput}>Focus</button>
    </>
  );
}
```

### Storing Mutable Values

```jsx
function Timer() {
  const [seconds, setSeconds] = useState(0);
  const intervalRef = useRef(null);

  const start = () => {
    intervalRef.current = setInterval(() => {
      setSeconds(s => s + 1);
    }, 1000);
  };

  const stop = () => {
    clearInterval(intervalRef.current);
  };

  return (
    <div>
      <p>Seconds: {seconds}</p>
      <button onClick={start}>Start</button>
      <button onClick={stop}>Stop</button>
    </div>
  );
}
```

---

## Error Boundaries

### Error Boundary Component

```jsx
class ErrorBoundary extends Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false, error: null };
  }

  static getDerivedStateFromError(error) {
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    console.error('Error caught:', error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      return <h1>Something went wrong.</h1>;
    }

    return this.props.children;
  }
}

// Usage
<ErrorBoundary>
  <MyComponent />
</ErrorBoundary>
```

---

## Performance Optimization

### React.memo

```jsx
// Prevents re-render if props haven't changed
const ExpensiveComponent = React.memo(({ data }) => {
  console.log('Rendering expensive component');
  return <div>{data}</div>;
});

// With custom comparison
const ExpensiveComponent = React.memo(
  ({ data }) => <div>{data}</div>,
  (prevProps, nextProps) => {
    return prevProps.data.id === nextProps.data.id;
  }
);
```

### useMemo & useCallback

```jsx
function OptimizedComponent({ items }) {
  // Memoize expensive calculation
  const sortedItems = useMemo(() => {
    return items.sort((a, b) => a.value - b.value);
  }, [items]);

  // Memoize function
  const handleClick = useCallback(() => {
    console.log('Clicked');
  }, []);

  return <ChildComponent onClick={handleClick} items={sortedItems} />;
}
```

### Code Splitting (Lazy Loading)

```jsx
import { lazy, Suspense } from 'react';

// Lazy load component
const HeavyComponent = lazy(() => import('./HeavyComponent'));

function App() {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <HeavyComponent />
      </Suspense>
    </div>
  );
}
```

---

## Advanced Patterns

### Higher-Order Components (HOC)

```jsx
function withAuth(Component) {
  return function AuthenticatedComponent(props) {
    const { isAuthenticated } = useAuth();

    if (!isAuthenticated) {
      return <Redirect to="/login" />;
    }

    return <Component {...props} />;
  };
}

// Usage
const ProtectedPage = withAuth(Dashboard);
```

### Render Props

```jsx
class Mouse extends Component {
  state = { x: 0, y: 0 };

  handleMouseMove = (event) => {
    this.setState({
      x: event.clientX,
      y: event.clientY
    });
  };

  render() {
    return (
      <div onMouseMove={this.handleMouseMove}>
        {this.props.render(this.state)}
      </div>
    );
  }
}

// Usage
<Mouse render={({ x, y }) => (
  <h1>Mouse position: {x}, {y}</h1>
)} />
```

### Compound Components

```jsx
function Tabs({ children }) {
  const [activeTab, setActiveTab] = useState(0);

  return (
    <div>
      {React.Children.map(children, (child, index) => {
        return React.cloneElement(child, {
          isActive: index === activeTab,
          onActivate: () => setActiveTab(index)
        });
      })}
    </div>
  );
}

function Tab({ isActive, onActivate, children }) {
  return (
    <button 
      onClick={onActivate}
      style={{ fontWeight: isActive ? 'bold' : 'normal' }}
    >
      {children}
    </button>
  );
}

// Usage
<Tabs>
  <Tab>Tab 1</Tab>
  <Tab>Tab 2</Tab>
  <Tab>Tab 3</Tab>
</Tabs>
```

### Portals

```jsx
import { createPortal } from 'react-dom';

function Modal({ children }) {
  return createPortal(
    <div className="modal">
      {children}
    </div>,
    document.getElementById('modal-root')
  );
}

// Usage
<Modal>
  <h1>Modal Content</h1>
</Modal>
```

### Forward Refs

```jsx
const FancyButton = forwardRef((props, ref) => (
  <button ref={ref} className="fancy-button">
    {props.children}
  </button>
));

// Usage
function App() {
  const ref = useRef();

  return <FancyButton ref={ref}>Click me</FancyButton>;
}
```

---

## PropTypes (Type Checking)

### Basic PropTypes

```jsx
import PropTypes from 'prop-types';

function Greeting({ name, age, isActive }) {
  return <div>Hello {name}</div>;
}

Greeting.propTypes = {
  name: PropTypes.string.isRequired,
  age: PropTypes.number,
  isActive: PropTypes.bool,
  callback: PropTypes.func,
  items: PropTypes.array,
  user: PropTypes.object,
  element: PropTypes.element,
  node: PropTypes.node,
  any: PropTypes.any
};

Greeting.defaultProps = {
  age: 18,
  isActive: false
};
```

### Advanced PropTypes

```jsx
MyComponent.propTypes = {
  // Array of specific type
  numbers: PropTypes.arrayOf(PropTypes.number),

  // Object with specific shape
  user: PropTypes.shape({
    name: PropTypes.string,
    age: PropTypes.number
  }),

  // Object with values of specific type
  scores: PropTypes.objectOf(PropTypes.number),

  // One of specific values
  status: PropTypes.oneOf(['active', 'inactive', 'pending']),

  // One of specific types
  value: PropTypes.oneOfType([
    PropTypes.string,
    PropTypes.number
  ]),

  // Instance of a class
  message: PropTypes.instanceOf(Message),

  // Custom validator
  customProp: (props, propName, componentName) => {
    if (!/matchme/.test(props[propName])) {
      return new Error('Validation failed!');
    }
  }
};
```

---

## Best Practices

### Component Organization

```jsx
// ✅ Good: One component per file
// UserProfile.jsx
import { useState } from 'react';
import './UserProfile.css';

function UserProfile({ user }) {
  const [isEditing, setIsEditing] = useState(false);

  return (
    <div className="user-profile">
      {/* Component JSX */}
    </div>
  );
}

export default UserProfile;
```

### Naming Conventions

```jsx
// ✅ Components: PascalCase
function UserProfile() {}
function TodoList() {}

// ✅ Hooks: camelCase with 'use' prefix
function useAuth() {}
function useFetch() {}

// ✅ Event handlers: 'handle' prefix
const handleClick = () => {};
const handleSubmit = () => {};

// ✅ Boolean props: 'is', 'has', 'should' prefix
<Button isDisabled hasIcon shouldValidate />
```

### Props Destructuring

```jsx
// ✅ Good: Destructure props
function UserCard({ name, email, avatar }) {
  return <div>{name}</div>;
}

// ❌ Avoid: Using props object
function UserCard(props) {
  return <div>{props.name}</div>;
}
```

### State Management

```jsx
// ✅ Group related state
const [user, setUser] = useState({
  name: '',
  email: '',
  age: 0
});

// ❌ Avoid: Too many separate states
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [age, setAge] = useState(0);

// ✅ Use functional updates when state depends on previous
setCount(prevCount => prevCount + 1);

// ❌ Avoid: Direct reference to current state
setCount(count + 1);
```

### Conditional Rendering

```jsx
// ✅ Good: Clear and readable
{isLoggedIn && <Dashboard />}
{error ? <ErrorMessage /> : <SuccessMessage />}

// ❌ Avoid: Nested ternaries
{isLoggedIn ? (
  isAdmin ? <AdminPanel /> : <UserPanel />
) : <Login />}

// ✅ Better: Extract to function or separate component
const renderPanel = () => {
  if (!isLoggedIn) return <Login />;
  if (isAdmin) return <AdminPanel />;
  return <UserPanel />;
};
```

### Key Props

```jsx
// ✅ Use unique IDs
{items.map(item => <div key={item.id}>{item.name}</div>)}

// ❌ Avoid index as key (when order changes)
{items.map((item, i) => <div key={i}>{item.name}</div>)}
```

### useEffect Dependencies

```jsx
// ✅ Include all dependencies
useEffect(() => {
  fetchUser(userId);
}, [userId]);

// ❌ Missing dependencies
useEffect(() => {
  fetchUser(userId);
}, []); // ESLint will warn

// ✅ Empty array for mount-only effect
useEffect(() => {
  console.log('Component mounted');
}, []);
```

### Avoid Inline Functions in JSX

```jsx
// ✅ Good: Define function outside JSX
function MyComponent() {
  const handleClick = () => {
    console.log('Clicked');
  };

  return <button onClick={handleClick}>Click</button>;
}

// ❌ Avoid: Inline function (creates new function on each render)
function MyComponent() {
  return (
    <button onClick={() => console.log('Clicked')}>
      Click
    </button>
  );
}
```

### Component Composition

```jsx
// ✅ Good: Small, focused components
function Header() {
  return (
    <header>
      <Logo />
      <Navigation />
      <UserMenu />
    </header>
  );
}

// ❌ Avoid: Large, monolithic components
function Header() {
  return (
    <header>
      {/* 200+ lines of JSX */}
    </header>
  );
}
```

---

## Common Patterns

### Loading States

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

  useEffect(() => {
    async function fetchUser() {
      try {
        setLoading(true);
        const response = await fetch(`/api/users/${userId}`);
        const data = await response.json();
        setUser(data);
      } catch (err) {
        setError(err.message);
      } finally {
        setLoading(false);
      }
    }

    fetchUser();
  }, [userId]);

  if (loading) return <Spinner />;
  if (error) return <Error message={error} />;
  if (!user) return <NotFound />;

  return <div>{user.name}</div>;
}
```

### Debouncing

```jsx
function SearchBox() {
  const [query, setQuery] = useState('');
  const [results, setResults] = useState([]);

  useEffect(() => {
    const timeoutId = setTimeout(() => {
      if (query) {
        searchAPI(query).then(setResults);
      }
    }, 500); // 500ms debounce

    return () => clearTimeout(timeoutId);
  }, [query]);

  return (
    <input
      value={query}
      onChange={e => setQuery(e.target.value)}
      placeholder="Search..."
    />
  );
}
```

### Pagination

```jsx
function PaginatedList({ items }) {
  const [currentPage, setCurrentPage] = useState(1);
  const itemsPerPage = 10;

  const totalPages = Math.ceil(items.length / itemsPerPage);
  const startIndex = (currentPage - 1) * itemsPerPage;
  const currentItems = items.slice(startIndex, startIndex + itemsPerPage);

  return (
    <div>
      <ul>
        {currentItems.map(item => (
          <li key={item.id}>{item.name}</li>
        ))}
      </ul>

      <div>
        <button 
          onClick={() => setCurrentPage(p => Math.max(1, p - 1))}
          disabled={currentPage === 1}
        >
          Previous
        </button>

        <span>Page {currentPage} of {totalPages}</span>

        <button 
          onClick={() => setCurrentPage(p => Math.min(totalPages, p + 1))}
          disabled={currentPage === totalPages}
        >
          Next
        </button>
      </div>
    </div>
  );
}
```

### Modal Management

```jsx
function App() {
  const [isModalOpen, setIsModalOpen] = useState(false);

  return (
    <div>
      <button onClick={() => setIsModalOpen(true)}>
        Open Modal
      </button>

      {isModalOpen && (
        <Modal onClose={() => setIsModalOpen(false)}>
          <h2>Modal Content</h2>
          <button onClick={() => setIsModalOpen(false)}>
            Close
          </button>
        </Modal>
      )}
    </div>
  );
}
```

---

## Testing

### Basic Component Test

```jsx
import { render, screen, fireEvent } from '@testing-library/react';
import Button from './Button';

test('button click updates count', () => {
  render(<Button />);

  const button = screen.getByText('Count: 0');
  fireEvent.click(button);

  expect(screen.getByText('Count: 1')).toBeInTheDocument();
});
```

### Testing Hooks

```jsx
import { renderHook, act } from '@testing-library/react';
import useCounter from './useCounter';

test('useCounter increments', () => {
  const { result } = renderHook(() => useCounter());

  act(() => {
    result.current.increment();
  });

  expect(result.current.count).toBe(1);
});
```

---

## Quick Reference

### Hooks at a Glance

| Hook | Purpose |
|------|---------|
| `useState` | Add state to functional components |
| `useEffect` | Perform side effects |
| `useContext` | Access context values |
| `useReducer` | Complex state logic |
| `useRef` | Access DOM or persist values |
| `useMemo` | Memoize expensive calculations |
| `useCallback` | Memoize functions |
| `useLayoutEffect` | Synchronous effects |
| `useImperativeHandle` | Customize ref exposure |

### Common Patterns Quick Reference

```jsx
// State
const [state, setState] = useState(initialValue);

// Effect (componentDidMount + componentDidUpdate + componentWillUnmount)
useEffect(() => {
  // Effect logic
  return () => {
    // Cleanup
  };
}, [dependencies]);

// Context
const value = useContext(MyContext);

// Ref
const ref = useRef(initialValue);

// Callback
const memoizedCallback = useCallback(() => {}, [deps]);

// Memo
const memoizedValue = useMemo(() => computeExpensiveValue(), [deps]);
```

---

## Resources & Tools

### Essential Tools
- **Create React App**: Quick start for React projects
- **Next.js**: React framework with SSR/SSG
- **Vite**: Fast build tool and dev server
- **React DevTools**: Browser extension for debugging

### State Management
- **Redux**: Predictable state container
- **Zustand**: Lightweight state management
- **Recoil**: Facebook's state management library
- **Jotai**: Atomic state management

### UI Libraries
- **Material-UI (MUI)**: Material Design components
- **Chakra UI**: Simple, modular components
- **Tailwind CSS**: Utility-first CSS framework
- **Ant Design**: Enterprise UI components

### Testing
- **Jest**: JavaScript testing framework
- **React Testing Library**: Test React components
- **Cypress**: E2E testing

### Documentation
- [Official React Docs](https://react.dev)
- [React TypeScript Cheatsheet](https://react-typescript-cheatsheet.netlify.app/)
- [Awesome React](https://github.com/enaqx/awesome-react)

---

## Common Gotchas

1. **State Updates Are Asynchronous**: Use functional updates when new state depends on old state
2. **Keys in Lists**: Always use unique, stable keys for list items
3. **useEffect Dependencies**: Include all dependencies used in the effect
4. **Event Handler Binding**: Use arrow functions or bind `this` in class components
5. **Mutating State**: Never mutate state directly, always use setState/setter function
6. **Stale Closures**: Be aware of closure scope in useEffect and event handlers
7. **Props vs State**: Props are immutable, state is mutable
8. **Component Re-renders**: Understanding when and why components re-render

---

*This comprehensive guide covers React fundamentals to advanced patterns. Bookmark for quick reference during development!*