Courses/React/Hooks (useState, useEffect)

    Lesson 5 • Intermediate

    Hooks Deep Dive ⚛️

    Go beyond useState and useEffect — master useRef, useMemo, useCallback, useReducer, and learn to create your own custom hooks.

    What You'll Learn in This Lesson

    • useRef for DOM access and persistent values
    • useMemo and useCallback for performance
    • useReducer for complex state logic
    • • Creating custom hooks for reusable logic
    • • Rules of Hooks and when to use each one

    1️⃣ useRef — Persistent References

    useRef creates a mutable container that persists across renders without causing re-renders. It's primarily used for DOM access and tracking values between renders.

    Try It: useRef

    Access DOM elements and track values without re-renders

    Try it Yourself »
    JavaScript
    // useRef — Persistent References
    console.log("=== useRef Hook ===");
    console.log("useRef holds a mutable value that persists across renders");
    console.log("WITHOUT triggering re-renders when changed.");
    console.log();
    
    console.log("=== DOM References ===");
    console.log("function TextInput() {");
    console.log("  const inputRef = useRef(null);");
    console.log();
    console.log("  function focusInput() {");
    console.log("    inputRef.current.focus(); // Direct DOM access!");
    console.log("  }");
    console.
    ...

    2️⃣ useMemo & useCallback

    These hooks optimize performance by memoizing values and functions. useMemo caches expensive calculations; useCallback caches function references to prevent unnecessary child re-renders.

    Try It: useMemo & useCallback

    Optimize performance with memoization

    Try it Yourself »
    JavaScript
    // useMemo & useCallback — Performance Optimization
    console.log("=== useMemo ===");
    console.log("Memoize expensive calculations so they only re-compute");
    console.log("when dependencies change.");
    console.log();
    
    console.log("// Without useMemo (runs every render):");
    console.log("const sorted = expensiveSort(items);");
    console.log();
    console.log("// With useMemo (only when items change):");
    console.log("const sorted = useMemo(() => expensiveSort(items), [items]);");
    console.log();
    
    // Simulatin
    ...

    3️⃣ useReducer — Complex State

    useReducer is an alternative to useState for complex state with multiple sub-values or when the next state depends on the previous one. It follows the dispatch → reducer → new state pattern.

    Try It: useReducer

    Manage complex state with the reducer pattern

    Try it Yourself »
    JavaScript
    // useReducer — Complex State Logic
    console.log("=== useReducer Hook ===");
    console.log("Like useState, but for complex state with multiple actions.");
    console.log("Inspired by Redux pattern: dispatch(action) → reducer → newState");
    console.log();
    
    // Reducer function
    function todoReducer(state, action) {
      switch (action.type) {
        case "ADD":
          return [...state, { id: Date.now(), text: action.text, done: false }];
        case "TOGGLE":
          return state.map(t => t.id === action.id ? { ...t,
    ...

    4️⃣ Custom Hooks

    Custom hooks let you extract reusable stateful logic into functions. They must start with use and can call other hooks. This is React's primary code reuse mechanism.

    Try It: Custom Hooks

    Build useLocalStorage, useToggle, and useFetch

    Try it Yourself »
    JavaScript
    // Custom Hooks — Reusable Logic
    console.log("=== Custom Hooks ===");
    console.log("Extract reusable stateful logic into functions.");
    console.log("Convention: must start with 'use' prefix.");
    console.log();
    
    // useLocalStorage hook
    console.log("=== Example: useLocalStorage ===");
    console.log("function useLocalStorage(key, initialValue) {");
    console.log("  const [value, setValue] = useState(() => {");
    console.log("    const stored = localStorage.getItem(key);");
    console.log("    return stored ? J
    ...

    ⚠️ Common Mistakes

    ⚠️
    Breaking Rules of Hooks — Never call hooks inside loops, conditions, or nested functions. Always call at the top level of your component.
    ⚠️
    Premature optimization — Don't wrap everything in useMemo/useCallback. Only optimize when you have a measured performance problem.
    💡
    Pro Tip: Install the eslint-plugin-react-hooks ESLint plugin — it catches hooks rule violations automatically.

    📋 Quick Reference

    HookPurpose
    useRefDOM access, persistent values
    useMemoCache expensive calculations
    useCallbackCache function references
    useReducerComplex state with actions
    Custom hooksReusable stateful logic (use* prefix)

    🎉 Lesson Complete!

    You've mastered the complete React hooks toolkit! Next, we'll build forms with controlled components and validation.

    Sign up for free to track which lessons you've completed and get learning reminders.

    Previous

    Cookie & Privacy Settings

    We use cookies to improve your experience, analyze traffic, and show personalized ads. You can manage your preferences below.

    By clicking "Accept All", you consent to our use of cookies for analytics and personalized advertising. You can customize your preferences or reject non-essential cookies.

    Privacy PolicyTerms of Service