React Hooks Deep Dive — useEffect, useMemo, useCallback Patterns

Master React hooks with practical examples. Covers useEffect dependencies, stale closures, memoization, and building custom hooks.

Overview

Master React hooks with practical examples. Covers useEffect dependencies, stale closures, memoization, and building custom hooks. This guide covers the essential concepts, practical examples, and production-ready patterns you need to get started.

Getting Started

Before diving in, make sure you have the necessary prerequisites installed. This guide assumes basic familiarity with the underlying technology stack.

Core Concepts

Understanding the fundamentals is essential before applying advanced patterns. The following sections break down the key ideas with working code examples.

Best Practices

  • Start simple and add complexity only when needed
  • Write tests alongside your implementation
  • Document decisions that aren't obvious from the code
  • Monitor in production with appropriate logging and metrics

Common Pitfalls

Developers commonly run into a few specific issues when first implementing these patterns. Understanding them upfront saves significant debugging time later.

Production Checklist

  • Error handling and graceful degradation
  • Logging and observability
  • Performance testing under realistic load
  • Security review

What are React Hooks?

Hooks are functions that let you "hook into" React state and lifecycle features from function components. Introduced in React 16.8, they've become the standard way to write React components.

useState Hook

import { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);
  const [user, setUser] = useState({ name: '', email: '' });
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

useEffect Hook

import { useState, useEffect } from 'react';

function UserProfile({ userId }) {
  const [user, setUser] = useState(null);
  
  // Runs on every render
  useEffect(() => {
    console.log('Component rendered');
  });
  
  // Runs only when userId changes
  useEffect(() => {
    fetchUser(userId).then(setUser);
  }, [userId]);
  
  // Cleanup function (componentWillUnmount)
  useEffect(() => {
    const subscription = subscribe();
    return () => subscription.unsubscribe();
  }, []);
}

useMemo and useCallback

import { useMemo, useCallback } from 'react';

function ExpensiveComponent({ items, onSelect }) {
  // Memoize expensive calculation
  const sortedItems = useMemo(() => {
    return items.sort((a, b) => a.value - b.value);
  }, [items]);
  
  // Memoize function to prevent re-renders
  const handleClick = useCallback((id) => {
    onSelect(id);
  }, [onSelect]);
  
  return sortedItems.map(item => (
    <div key={item.id} onClick={() => handleClick(item.id)}>
      {item.name}
    </div>
  ));
}

Custom Hooks

function useLocalStorage(key, initialValue) {
  const [storedValue, setStoredValue] = useState(() => {
    const item = window.localStorage.getItem(key);
    return item ? JSON.parse(item) : initialValue;
  });

  const setValue = (value) => {
    setStoredValue(value);
    window.localStorage.setItem(key, JSON.stringify(value));
  };

  return [storedValue, setValue];
}

// Usage
function ThemeToggle() {
  const [theme, setTheme] = useLocalStorage('theme', 'light');
  return <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>Toggle</button>;
}

Common Mistakes

  • Missing dependencies in useEffect
  • Using hooks inside conditions or loops
  • Over-using useMemo/useCallback (premature optimization)
  • Not cleaning up effects (memory leaks)
  • Stale closures in callbacks
→ Explore DevKits Free Developer Tools
aiforeverthing.com — JavaScript tools, CSS beautifiers, and more

Frequently Asked Questions

When should I use useMemo?

Only for expensive calculations or to maintain reference equality. Don't wrap everything.

Why do I get "React Hook called conditionally" error?

Hooks must be called in the same order every render. Never call them inside if statements or loops.

→ Explore DevKits Free Developer Tools
aiforeverthing.com — No signup, runs in your browser