[Solved] Uncaught Invariant Violation: Rendered more hooks than during the previous render
When you are working with React Hooks, you may see the error: Uncaught Invariant Violation: Rendered more hooks than during the previous render. In this article, we will show you how to fix this article.
If we conditionally call a hook or return before all of the hooks have finished, we get the error "Rendered more hooks than during the last render". Move all hooks to the top level of the function component and avoid using hooks within conditions to fix the problem.
Checkout more articles on ReactJS
- How to access URL parameters in the class component using React Router v6
- How to create a vertical timeline component in React
- Multiple useReducer Hook in React
- Detect click outside a react component using React Hooks
- [Solved] ref not working with React Redux connect
Error
Uncaught Invariant Violation: Rendered more hooks than during the previous render.
Error - Uncaught Invariant Violation: Rendered more hooks than during the previous render - Clue Mediator
Letโs take an example of how the error occurs and how to fix it.
Example 1
import React, {useEffect, useState} from 'react';
function App() {
const [counter, setCounter] = useState(0);
// Error: Rendered more hooks than during the previous render.
if (counter > 0) {
// Calling React hook conditionally
useEffect(() => {
console.log('hello world');
});
}
return (
<div>
<button onclick="{()" ==""> setCounter(counter + 1)}>toggle loading</button>
<h1>Hello world</h1>
</div>
);
}
export default App;
Solution:
Because React hooks can only be invoked at the top level, we must relocate the condition within the hook to fix the issue.
import React, {useEffect, useState} from 'react';
function App() {
const [counter, setCounter] = useState(0);
// hook is called at top level (not conditionally)
useEffect(() => {
if (counter > 0) {
console.log('hello world');
}
});
return (
<div>
<button onclick="{()" ==""> setCounter(counter + 1)}>toggle loading</button>
<h1>Hello world</h1>
</div>
);
}
export default App;
Example 2
import React, {useState} from 'react';
function App() {
const [counter, setCounter] = useState(0);
// this returns before second hook runs if condition is met
if (counter > 0) {
return <h2>Returning early</h2>;
}
// Error because hook is called conditionally
const [color, setColor] = useState('salmon');
return (
<div>
<button onclick="{()" ==""> setCounter(counter + 1)}>toggle loading</button>
<h1>Hello world</h1>
</div>
);
}
export default App;
Solution:
To fix the issue, we must shift all hooks to the component's top level, above any circumstances that can result in a return value.
import React, {useState} from 'react';
export default function App() {
const [counter, setCounter] = useState(0);
const [color, setColor] = useState('salmon');
// condition that may return early must be below all hooks
if (counter > 0) {
return <h2>Returning early</h2>;
}
return (
<div>
<button onclick="{()" ==""> setCounter(counter + 1)}>toggle loading</button>
<h1>Hello world</h1>
</div>
);
}
export default App;
Conclusion
- Call hooks only at the top level.
- Calling hooks inside of loops, conditions, or nested functions is not recommended.
- Use hooks first, before any early returns, in the top level of your React method.
- Only call hooks from React function components or from custom hooks.
I hope you find this article helpful.
Thank you for reading. Happy Coding..!! ๐