How to fix Rendered more hooks than during the previous render in React

ReactINTERMEDIATEHIGHUpdated Dec 8, 2025· 139 views

This error occurs when the number of React hooks called changes between renders, typically because hooks are placed inside conditions, loops, or after early returns. React requires hooks to be called in the exact same order on every render to properly track component state.

Quick fix

Fixes Rendered more hooks than during the previous render

function MyComponent({ isLoggedIn }) {
  if (!isLoggedIn) {
    return <Login />;
  }

  // ❌ This hook only runs when isLoggedIn is true
  const [user, setUser] = useState(null);
  return <div>{user?.name}</div>;
}
  1. Move all hooks to the top level of your component
  2. Move conditional logic inside hooks instead of around them
  3. Extract conditional components into separate child components
  4. Replace direct component function calls with JSX syntax
react — error
function MyComponent({ isLoggedIn }) {
if (!isLoggedIn) {
return <Login />;
}
// ❌ This hook only runs when isLoggedIn is true
const [user, setUser] = useState(null);
return <div>{user?.name}</div>;
}
Rendered more hooks than during the previous render

What this error means

This error indicates that React detected a change in the number of hooks being called during a component's render cycle. React hooks (like useState, useEffect, useContext) must be called in the exact same order on every render because React tracks them using their call order in an internal linked list structure. When a hook is skipped or called conditionally on one render but not the next, React's internal tracking becomes misaligned. The framework expects the same sequence of hooks each time, and any deviation causes this error to be thrown. This is a fundamental requirement of how React's hooks system works - it relies on consistent call order rather than unique identifiers to associate each hook with its corresponding state and effects. The error message specifically means that on the current render, React encountered more hook calls than it did on the previous render, which violates the Rules of Hooks and indicates that hook calls are happening conditionally or in an inconsistent manner.

Typical symptoms

  • Application crashes with "Rendered more hooks than during the previous render" error message
  • Error occurs after conditional logic changes (like toggling a feature flag or authentication state)
  • Component works initially but breaks when re-rendering with different props or state
  • Console shows "React has detected a change in the order of Hooks" warning
  • ESLint with react-hooks plugin shows warnings about conditional hook usage
  • Development mode shows the error but the exact cause is unclear from the stack trace
  • Error happens when returning early from a component before all hooks are called

Common causes

  1. Calling hooks (useState, useEffect, etc.) inside if statements or conditional blocks
  2. Placing hooks after an early return statement that sometimes executes and sometimes doesn't
  3. Using hooks inside loops or iterating over arrays to generate multiple hook calls
  4. Calling a component function directly (like MyComponent()) instead of using JSX (<MyComponent />)
  5. Nesting hooks inside callback functions or event handlers instead of at the component top level
  6. Conditionally rendering a component that contains hooks based on state or props
  7. Having different code paths that call different numbers of hooks based on runtime conditions
  8. Using hooks after conditional returns or throw statements that don't always execute

How to fix "Rendered more hooks than during the previous render"

1Move all hooks to the top level of your component

Ensure all hook calls happen before any conditional logic or return statements. Hooks must always execute in the same order.

Before (incorrect):

jsx
function MyComponent({ isLoggedIn }) {
  if (!isLoggedIn) {
    return <Login />;
  }

  // ❌ This hook only runs when isLoggedIn is true
  const [user, setUser] = useState(null);
  return <div>{user?.name}</div>;
}

After (correct):

jsx
function MyComponent({ isLoggedIn }) {
  // ✅ Hook is always called at the top level
  const [user, setUser] = useState(null);

  if (!isLoggedIn) {
    return <Login />;
  }

  return <div>{user?.name}</div>;
}
2Move conditional logic inside hooks instead of around them

If you need conditional behavior, place the condition inside the hook rather than conditionally calling the hook itself.

Before (incorrect):

jsx
function MyComponent({ shouldFetch }) {
  if (shouldFetch) {
    // ❌ Hook only called when shouldFetch is true
    useEffect(() => {
      fetchData();
    }, []);
  }
}

After (correct):

jsx
function MyComponent({ shouldFetch }) {
  // ✅ Hook always called, condition moved inside
  useEffect(() => {
    if (shouldFetch) {
      fetchData();
    }
  }, [shouldFetch]);
}
3Extract conditional components into separate child components

When you need to conditionally use hooks, create a separate component that always calls its hooks in a consistent order.

Before (incorrect):

jsx
function Dashboard({ userType }) {
  if (userType === 'admin') {
    const [stats, setStats] = useState(null); // ❌ Conditional hook
    return <AdminDashboard stats={stats} />;
  }
  return <UserDashboard />;
}

After (correct):

jsx
function AdminDashboardWrapper() {
  const [stats, setStats] = useState(null); // ✅ Always called
  return <AdminDashboard stats={stats} />;
}

function Dashboard({ userType }) {
  if (userType === 'admin') {
    return <AdminDashboardWrapper />;
  }
  return <UserDashboard />;
}
4Replace direct component function calls with JSX syntax

If you're calling component functions directly instead of using JSX, this can disrupt React's render cycle and hook tracking.

Before (incorrect):

jsx
function App() {
  const [count, setCount] = useState(0);
  // ❌ Calling component as a function
  return MyComponent({ count });
}

After (correct):

jsx
function App() {
  const [count, setCount] = useState(0);
  // ✅ Using JSX syntax
  return <MyComponent count={count} />;
}
5Check for hooks inside loops and remove them

Never call hooks while iterating over arrays or in any kind of loop structure.

Before (incorrect):

jsx
function ItemList({ items }) {
  return items.map(item => {
    // ❌ Hook called in a loop - number changes with items.length
    const [selected, setSelected] = useState(false);
    return <Item key={item.id} selected={selected} />;
  });
}

After (correct):

jsx
function ListItem({ item }) {
  // ✅ Hook in separate component
  const [selected, setSelected] = useState(false);
  return <Item selected={selected} />;
}

function ItemList({ items }) {
  return items.map(item => (
    <ListItem key={item.id} item={item} />
  ));
}
6Enable ESLint rules for hooks to catch violations

Install and configure eslint-plugin-react-hooks to automatically detect hook rule violations during development.

bash
npm install eslint-plugin-react-hooks --save-dev

Add to your .eslintrc.json:

json
{
  "plugins": ["react-hooks"],
  "rules": {
    "react-hooks/rules-of-hooks": "error",
    "react-hooks/exhaustive-deps": "warn"
  }
}

This will show errors in your editor when you violate the Rules of Hooks, catching issues before runtime.

7Review custom hooks for conditional hook calls

If you're using custom hooks, ensure they also follow the Rules of Hooks and don't call hooks conditionally.

Before (incorrect):

jsx
function useAuth(requireAuth) {
  if (requireAuth) {
    // ❌ Conditional hook in custom hook
    const user = useContext(AuthContext);
    return user;
  }
  return null;
}

After (correct):

jsx
function useAuth() {
  // ✅ Always call the hook
  const user = useContext(AuthContext);
  return user;
}

// Use conditional logic at the call site instead
function MyComponent({ requireAuth }) {
  const user = useAuth();

  if (requireAuth && !user) {
    return <Login />;
  }
  return <Dashboard />;
}

Advanced notes

Why React uses call order: React's hooks implementation relies on a linked list data structure where each hook call adds a node in sequence. This design choice makes the implementation fast and memory-efficient, but requires strict ordering rules. Alternative designs using unique IDs or keys were considered but rejected due to performance overhead and developer experience concerns.

Next.js and Server Components: In Next.js 13+, be aware that Server Components cannot use hooks at all. Only Client Components (marked with 'use client') can use hooks. Mixing these patterns incorrectly can cause confusing hook errors.

Testing considerations: When writing tests, ensure your test cases exercise all code paths. A component might work in one test scenario but fail in another if hooks are conditionally called based on props or state that differ between tests.

React DevTools: The React DevTools extension can help visualize the hooks tree for a component. When debugging this error, use DevTools to inspect which hooks are being called and in what order during different renders.

Concurrent React and Suspense: With React 18's concurrent features, components may render multiple times or partially. Hook order violations become even more critical in this context as renders may be interrupted and restarted.

Prevention best practices:
- Always use the ESLint plugin for real-time feedback
- Extract complex conditional rendering into separate components
- Keep all hooks at the very top of your function body
- Use TypeScript to catch structural issues earlier
- Review custom hooks with the same scrutiny as components

Frequently asked questions

What does "Rendered more hooks than during the previous render" mean?
This error indicates that React detected a change in the number of hooks being called during a component's render cycle. React hooks (like useState, useEffect, useContext) must be called in the exact same order on every render because React tracks them using their call order in an internal linked list structure. When a hook is skipped or called conditionally on one render but not the next, React's internal tracking becomes misaligned.
How do I fix "Rendered more hooks than during the previous render"?
This error occurs when the number of React hooks called changes between renders, typically because hooks are placed inside conditions, loops, or after early returns. React requires hooks to be called in the exact same order on every render to properly track component state.
What causes "Rendered more hooks than during the previous render"?
Calling hooks (useState, useEffect, etc.) inside if statements or conditional blocks Placing hooks after an early return statement that sometimes executes and sometimes doesn't Using hooks inside loops or iterating over arrays to generate multiple hook calls
Is the "Rendered more hooks than during the previous render" error serious?
Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.

Official resources & further reading