Error: Rendered more hooks than during the previous render.
You’re calling hooks conditionally or after an early return. React requires hooks to be called in the exact same order every render.
Fix 1: Move hooks before any early returns
// ❌ Hook after early return
function Profile({ userId }) {
if (!userId) return <p>No user</p>;
const [user, setUser] = useState(null); // Hook after return!
// ...
}
// ✅ All hooks at the top
function Profile({ userId }) {
const [user, setUser] = useState(null); // Always called
if (!userId) return <p>No user</p>;
// ...
}
Fix 2: Don’t put hooks inside conditions
// ❌ Conditional hook
function App({ isLoggedIn }) {
if (isLoggedIn) {
const [name, setName] = useState(''); // Conditional!
}
}
// ✅ Always call the hook, conditionally use the value
function App({ isLoggedIn }) {
const [name, setName] = useState('');
// Only use `name` when isLoggedIn is true
}
Fix 3: Don’t put hooks inside loops
// ❌ Hook in a loop
function List({ items }) {
items.forEach(item => {
const [selected, setSelected] = useState(false); // In a loop!
});
}
// ✅ Extract to a child component
function ListItem({ item }) {
const [selected, setSelected] = useState(false);
return <li onClick={() => setSelected(!selected)}>{item.name}</li>;
}
function List({ items }) {
return items.map(item => <ListItem key={item.id} item={item} />);
}
The rule
Hooks must be called at the top level of your component, in the same order, every render. No conditions, no loops, no early returns before hooks.
See also: React invalid hook call fix | React Hooks cheat sheet