Lesson 25 +10 XP

The Rules of Hooks

The Rules of Hooks

React Hooks (useState, useEffect, useContext, etc.) enable functional components to tap into React state and lifecycle features. However, React relies on strict internal execution call orders, leading to two fundamental Rules of Hooks.

Rule 1: Only Call Hooks at the Top Level

Do not call Hooks inside loops, conditions, nested functions, or try/catch blocks. Always use Hooks at the top level of your React function, before any early returns.

// ❌ WRONG: Calling Hook inside a condition
function Profile({ isLoaded }) {
  if (isLoaded) {
    // Error! Breaking top-level execution order!
    useEffect(() => { fetchProfile(); }, []);
  }
  return <div>Profile</div>;
}

// ✅ CORRECT: Always call Hook at top level; place condition INSIDE the hook
function Profile({ isLoaded }) {
  useEffect(() => {
    if (isLoaded) {
      fetchProfile();
    }
  }, [isLoaded]);

  return <div>Profile</div>;
}

Why Top-Level Calling is Mandatory

React does not track state using variable names; it relies on the exact index order in which Hooks are called during component renders. If a condition skips a Hook call, all subsequent Hook call indices get misaligned, breaking component state memory!

Rule 2: Only Call Hooks from React Functions

Call Hooks exclusively from:

  1. React Functional Components.
  2. Custom Hooks (functions starting with use...).

Do not call Hooks from regular JavaScript utility functions outside component lifecycles.

Allowed Call LocationsDisallowed Call Locations
Top level of React Functional ComponentInside if / else conditional blocks
Inside Custom Hook (useFetch, useAuth)Inside for or while loops
Top level before any early return statementInside standard non-React JS functions

Summary & TL;DR

  • Rule 1: Only call Hooks at the top level. Never inside conditions, loops, or nested functions.
  • Rule 2: Only call Hooks from React functional components or custom Hooks.
  • React relies on Hook call order consistency across renders.