Why React Hooks should only be used at the top level of functional components

React hooks should only be used at the top level (root) of a functional component or custom hook — not inside loops, conditions, or nested functions. This is a core rule of React hooks.

ReactHooks

React hooks should only be used at the top level (root) of a functional component or custom hook — not inside loops, conditions, or nested functions. This is a core rule of React hooks. Here's why:

  1. Consistent Hook Order means Stable State

React relies on the order in which hooks are called to associate them with state and effects. For example:

function MyComponent() {
  const [count, setCount] = useState(0); // 1st hook
  const [name, setName] = useState(""); // 2nd hook
}

in This scenario, React knows:

  • 1st call → count
  • 2nd call → name

If this rule were violated, e.g., put a hook inside a conditional:

if (someCondition) {
  useState(123);
}

Then the number and order of hooks can change between renders, which breaks React’s internal hook tracking, leading to bugs.

  1. Avoiding Conditional Hook Execution

Hooks must be called unconditionally, every time the component renders, to ensure React’s internal hook state is consistent:

// incorrect
function Component() {
  if (user.isLoggedIn) {
    useEffect(() => {
      console.log("User is logged in");
    }, []);
  }
}

// correct
function Component() {
  useEffect(() => {
    if (user.isLoggedIn) {
      console.log("User is logged in");
    }
  }, []);
}
  1. Custom Hooks Must Follow the Same Rule

When you create your own custom hooks, the same rule applies — call them at the top level of your component or other hooks.

// incorrect
function Component() {
  function doSomething() {
    useMyCustomHook(); // Can't call a hook inside another function
  }
}
// correct
function Component() {
  const result = useMyCustomHook(); // Top level
}