React - Hooks: Complete Index

They allow you to use React state and features in functional components, making the code simpler and more reusable.


Organization of Hooks

This section is organized into several specialized chapters for better understanding:

📚 Basic Hooks

15.0.4.0 - useState

  • Local state in functional components
  • Management of state updates
  • Optimization and best practices
  • Practical examples with objects and arrays

15.0.4.1 - useEffect

  • Side effects and lifecycle
  • Common patterns: fetch, timers, events
  • Dependencies and optimizations
  • Cleanup and memory leak management

15.0.4.2 - useRef

  • Direct DOM references
  • Mutable values without re-render
  • Advanced use cases: timers, intersection observer
  • Difference with useState

⚡ Performance Hooks

15.0.4.3 - useMemo

  • Memoization of expensive calculations
  • Optimization of objects and arrays
  • When and how to use useMemo
  • Impact on performance

15.0.4.4 - useCallback

  • Memoization of functions
  • Avoiding unnecessary re-renders
  • Optimization of child components
  • Patterns with events

🏗️ State Management Hooks

15.0.4.5 - useReducer

  • Complex state management
  • Integrated Redux-like pattern
  • Actions and reducers
  • Use cases vs useState

15.0.4.6 - useContext

  • Sharing data between components
  • Solving prop drilling
  • Context API and providers
  • Patterns with multiple contexts

🚀 Advanced Hooks

15.0.4.7 - Advanced Hooks

  • useLayoutEffect: DOM synchronization
  • useId: unique identifiers
  • useTransition: non-blocking transitions
  • useDeferredValue: deferred values

🎨 Custom Hooks

15.0.4.8 - Custom Hooks

  • Creating your own hooks
  • Reusability and shared logic
  • Common patterns: API, UI, utilities
  • Composition and best practices

Quick Overview

Native React Hooks

import {
  useState,         // Local state
  useEffect,        // Side effects
  useRef,           // DOM references/mutable values
  useMemo,          // Memoization of calculations
  useCallback,      // Memoization of functions
  useReducer,       // Complex state
  useContext,       // Global context
  useLayoutEffect,  // Synchronous effects
  useId,            // Unique identifiers
  useTransition,    // UI Transitions
  useDeferredValue  // Deferred values
} from 'react'

Custom Hook Example

// Simple custom hook
function useCounter(initialValue = 0) {
  const [count, setCount] = useState(initialValue)

  const increment = useCallback(() => setCount(c => c + 1), [])
  const decrement = useCallback(() => setCount(c => c - 1), [])
  const reset = useCallback(() => setCount(initialValue), [initialValue])

  return { count, increment, decrement, reset }
}

// Usage
function App() {
  const { count, increment, decrement, reset } = useCounter(10)

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>+1</button>
      <button onClick={decrement}>-1</button>
      <button onClick={reset}>Reset</button>
    </div>
  )
}

Rules of Hooks

⚠️ Important Rules

  1. Always at the root level: never in loops, conditions, or nested functions
  2. Only in React components or other custom hooks
  3. Constant order: the order of calls must be identical on each render
  4. Naming: custom hooks start with "use"
// ✅ GOOD
function GoodComponent() {
  const [count, setCount] = useState(0)
  const [name, setName] = useState('')
  
  useEffect(() => {
    document.title = `${name} - ${count}`
  }, [name, count])
  
  return <div>...</div>
}

// ❌ BAD
function BadComponent({ condition }) {
  const [count, setCount] = useState(0)
  
  if (condition) {
    const [name, setName] = useState('') // ❌ Conditional Hook!
    useEffect(() => {}) // ❌ Conditional Hook!
  }
  
  return <div>...</div>
}

Common Patterns

Data Fetching

function useApiData(url) {
  const [data, setData] = useState(null)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState(null)

  useEffect(() => {
    fetch(url)
      .then(res => res.json())
      .then(setData)
      .catch(setError)
      .finally(() => setLoading(false))
  }, [url])

  return { data, loading, error }
}

Local State Management

function useFormState(initialState) {
  const [values, setValues] = useState(initialState)
  const [errors, setErrors] = useState({})

  const setValue = useCallback((name, value) => {
    setValues(prev => ({ ...prev, [name]: value }))
    setErrors(prev => ({ ...prev, [name]: null }))
  }, [])

  const setError = useCallback((name, error) => {
    setErrors(prev => ({ ...prev, [name]: error }))
  }, [])

  return { values, errors, setValue, setError }
}

UI State

function useToggle(initialValue = false) {
  const [value, setValue] = useState(initialValue)
  const toggle = useCallback(() => setValue(v => !v), [])
  return [value, toggle]
}

function useModal() {
  const [isOpen, setIsOpen] = useState(false)
  const open = useCallback(() => setIsOpen(true), [])
  const close = useCallback(() => setIsOpen(false), [])
  return { isOpen, open, close }
}

Class → Hooks Migration

Before (Class Component)

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

  componentDidMount() {
    document.title = `Count: ${this.state.count}`
  }

  componentDidUpdate() {
    document.title = `Count: ${this.state.count}`
  }

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

  render() {
    return (
      <div>
        <p>{this.state.count}</p>
        <button onClick={this.increment}>+1</button>
      </div>
    )
  }
}

After (Hooks)

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

  useEffect(() => {
    document.title = `Count: ${count}`
  }, [count])

  const increment = useCallback(() => {
    setCount(prev => prev + 1)
  }, [])

  return (
    <div>
      <p>{count}</p>
      <button onClick={increment}>+1</button>
    </div>
  )
}

Additional Resources