[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
Error
Uncaught Invariant Violation: Rendered more hooks than during the previous render.
Let’s take an example of how the error occurs and how to fix it.
Example 1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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..!! 🙂
Thank you so much. This was very helpful.
You’re very welcome! I’m delighted to hear that you found the information helpful. If you have any more questions or need further assistance with anything else, whether it’s related to web development or any other topic, feel free to ask. Happy coding, and have a great day! 😊🚀