React Hook called conditionally - Rules of Hooks Fix (2026) | Tutorials Logic
What is This Error?
The "React Hook is called conditionally" error occurs when you call a React Hook inside a conditional statement, loop, or nested function. React requires that Hooks are always called in the same order on every render — this is one of the fundamental Rules of Hooks.
Error Message:
React Hook "useState" is called conditionally. React Hooks must be called in the exact same order in every component render.
Common Causes
Quick Fix (TL;DR)
// ❌ Problem — Hook inside condition
function App({ isLoggedIn }) {
if (isLoggedIn) {
const [user, setUser] = useState(null); // Error!
}
}
// ✅ Solution — always call Hook at top level
function App({ isLoggedIn }) {
const [user, setUser] = useState(null); // Always called
if (!isLoggedIn) return null; // Condition after hooks
}
Common Scenarios & Solutions
Scenario 1: Hook Inside if Statement
function UserProfile({ showDetails }) {
if (showDetails) {
const [details, setDetails] = useState({}); // ❌ Conditional hook!
useEffect(() => { fetchDetails(); }, []); // ❌ Conditional hook!
}
return Profile;
}
function UserProfile({ showDetails }) {
// ✅ Always call hooks at the top level
const [details, setDetails] = useState({});
useEffect(() => {
if (showDetails) { // ✅ Condition inside the hook
fetchDetails().then(setDetails);
}
}, [showDetails]);
return {showDetails && {details.bio}
};
}
Scenario 2: Hook After Early Return
function Dashboard({ user }) {
if (!user) return Please log in
; // Early return
const [data, setData] = useState([]); // ❌ Hook after return!
useEffect(() => { fetchData(); }, []); // ❌ Hook after return!
return {data.map(item => {item}
)};
}
function Dashboard({ user }) {
// ✅ All hooks BEFORE any return
const [data, setData] = useState([]);
useEffect(() => {
if (user) fetchData().then(setData); // Condition inside effect
}, [user]);
if (!user) return Please log in
; // Return AFTER hooks
return {data.map(item => {item}
)};
}
Scenario 3: Hook Inside a Loop
function ItemList({ items }) {
return items.map(item => {
const [selected, setSelected] = useState(false); // ❌ Hook in loop!
return setSelected(!selected)}>{item};
});
}
// ✅ Extract to a separate component
function Item({ item }) {
const [selected, setSelected] = useState(false); // ✅ Top level
return (
setSelected(!selected)}>
{item} {selected ? '✓' : ''}
);
}
function ItemList({ items }) {
return items.map(item => );
}
Scenario 4: Conditional Custom Hook
function App({ isAdmin }) {
if (isAdmin) {
const adminData = useAdminData(); // ❌ Conditional custom hook!
}
}
// ✅ Always call the hook, pass condition as parameter
function App({ isAdmin }) {
const adminData = useAdminData(isAdmin); // Hook decides internally
}
// Inside useAdminData:
function useAdminData(isAdmin) {
const [data, setData] = useState(null);
useEffect(() => {
if (isAdmin) fetchAdminData().then(setData); // Condition inside
}, [isAdmin]);
return data;
}
Best Practices to Avoid This Error
Related Errors
Key Takeaways
- React Hooks must always be called in the same order on every render
- Never call Hooks inside if/else, loops, or nested functions
- Always place all Hook calls at the top of your component, before any returns
- Put conditions inside Hooks (e.g., inside useEffect), not around them
- Extract list items into separate components to use Hooks per item
- Use eslint-plugin-react-hooks to automatically catch Rules of Hooks violations
Frequently Asked Questions
Level Up Your React js Skills
Master React js with these hand-picked resources
10,000+ learners
Free forever
Updated 2026
Related React Topics