Web30 min · Lesson 1 of 17

useState, useEffect & Custom Hooks

Move beyond classes. Manage local state and side effects with the primary React hooks and build reusable custom hooks.

Functional React

In modern React, everything is a function. useState provides persistent values across renders, while useEffect synchronizes with external systems like APIs and subscriptions.

import { useState, useEffect, useCallback } from "react"

interface User {
  id: string
  name: string
  email: string
}

function useUser(userId: string | null) {
  const [user, setUser] = useState(null)
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState(null)

  useEffect(() => {
    if (!userId) return
    let cancelled = false

    setLoading(true)
    fetch(`/api/users/${userId}`)
      .then(res => res.json())
      .then(data => {
        if (!cancelled) setUser(data)
      })
      .catch(err => {
        if (!cancelled) setError(err)
      })
      .finally(() => {
        if (!cancelled) setLoading(false)
      })

    return () => { cancelled = true }
  }, [userId])

  return { user, loading, error }
}

Custom Hooks

Extract complex state logic into reusable, testable functions. Custom hooks are the primary mechanism for logic reuse in React.