React Hooks Order Error: The Component Extraction Pattern
October 2025
I've run into this React error so many times, and every time I promise myself I'll document it for future me. Today, after what feels like the millionth time, I'm sharing it here in case it helps someone else.
The Error
Error: Rendered more hooks than during the previous render
React expects hooks to be called in the same order on every render. When that doesn't happen, you get this error.
The Problem
My component needed a prop that only becomes available after the page finishes loading. But I was using that prop to fetch some data from the backend.
Here's how it played out:
First render
- Prop is missing
- Component skips
useQuery - Component runs other hooks
Second render
- Prop becomes available
- Component now runs
useQuery+ other hooks
React sees a different number of hooks between renders → error.
Here's what the problematic code looked like:
function UserProfile({ userId }: { userId?: string }) { const [settings, setSettings] = useState({}); // This hook only runs when userId exists if (userId) { const { data } = useQuery({ queryKey: ['user', userId], queryFn: () => fetchUser(userId), }); } // More hooks that always run const [theme, setTheme] = useState('dark'); return <div>...</div>; }
The issue: useQuery is conditionally called, which violates React's Rules of Hooks.
The Fix: Component Extraction Pattern
Split into two components:
- Outer component: Waits until the prop exists (shows loading)
- Inner component: Runs all the data-fetching hooks unconditionally
Here's the solution:
// Outer component - handles loading state function UserProfile({ userId }: { userId?: string }) { if (!userId) { return <div>Loading...</div>; } return <UserProfileContent userId={userId} />; } // Inner component - all hooks run unconditionally function UserProfileContent({ userId }: { userId: string }) { const [settings, setSettings] = useState({}); // This hook always runs now const { data } = useQuery({ queryKey: ['user', userId], queryFn: () => fetchUser(userId), }); const [theme, setTheme] = useState('dark'); return <div>...</div>; }
When to Use This Pattern
Use this pattern any time your component:
- Depends on props that load after the first render
- Needs to run hooks that depend on those props (like
useQuery,useMutation, etc.)
The Takeaway
React's Rules of Hooks aren't just guidelines - they're requirements. Hooks must be called in the same order every render. When props load asynchronously, extract components to ensure hooks always run in the same order.
This pattern can save you a few hours of debugging (and a few 🤦♀️ moments).