This error occurs when React Hooks are called outside the body of a function component or custom Hook, violating one of React's fundamental rules. The error typically happens due to version mismatches, calling Hooks in class components, or placing Hooks inside loops, conditions, or nested functions.
This error is React's way of enforcing the Rules of Hooks, which are essential for React to maintain component state correctly across renders. Hooks like useState, useEffect, and useContext rely on being called in the exact same order every time a component renders. When React detects a Hook being called outside a function component or custom Hook, or in a place where the call order might change (like inside a loop or condition), it throws this error to prevent unpredictable behavior. The error occurs because React internally uses the order of Hook calls to associate each Hook with its corresponding state. If Hooks are called conditionally or outside function components, React cannot guarantee this order will remain consistent, which would break the state management system and lead to bugs where components don't update correctly or lose their state between renders. Understanding this error is crucial because it represents one of the most fundamental constraints in modern React development. Unlike class components where lifecycle methods could be called anywhere, Hooks have strict placement rules that must be followed to ensure React's rendering system works correctly.
Review your code to ensure all Hook calls are at the top level of your function component, before any early returns, loops, or conditions. Hooks must be called in the exact same order on every render.
Bad - Hook inside condition:
function MyComponent() {
if (condition) {
const [state, setState] = useState(0); // ❌ Error!
}
return <div>Content</div>;
}Good - Hook at top level:
function MyComponent() {
const [state, setState] = useState(0); // ✓ Correct
if (condition) {
// Use state here
}
return <div>Content</div>;
}If you're calling Hooks inside event handlers or utility functions, move the Hook call to the component level and pass the state or values down instead.
Bad - Hook in event handler:
function MyComponent() {
const handleClick = () => {
const [count, setCount] = useState(0); // ❌ Error!
setCount(count + 1);
};
return <button onClick={handleClick}>Click</button>;
}Good - Hook at component level:
function MyComponent() {
const [count, setCount] = useState(0); // ✓ Correct
const handleClick = () => {
setCount(count + 1);
};
return <button onClick={handleClick}>Click {count}</button>;
}Verify that your react and react-dom versions match and are both 16.8.0 or higher (Hooks were introduced in 16.8.0).
npm ls react react-domIf versions don't match or are below 16.8.0, update them:
npm install react@latest react-dom@latestOr specify matching versions:
npm install [email protected] [email protected]After updating, clear your cache and reinstall:
rm -rf node_modules package-lock.json
npm installMultiple React copies in node_modules can cause this error. Check for duplicates:
npm ls reactIf you see multiple versions listed, this is your problem. Common causes:
For npm link or local packages:
# In your linked package
npm link react react-dom
# In your main project
npm linkFor monorepos or workspaces:
Add to your package.json:
{
"resolutions": {
"react": "18.2.0",
"react-dom": "18.2.0"
}
}Then reinstall:
rm -rf node_modules package-lock.json
npm installIf you're trying to use Hooks in a class component, you must convert it to a function component first. Hooks cannot be used in classes.
Before - Class component:
class MyComponent extends React.Component {
render() {
const [count, setCount] = useState(0); // ❌ Error!
return <div>{count}</div>;
}
}After - Function component:
function MyComponent() {
const [count, setCount] = useState(0); // ✓ Correct
return <div>{count}</div>;
}Or with arrow function:
const MyComponent = () => {
const [count, setCount] = useState(0);
return <div>{count}</div>;
};If you need to share Hook logic between components, extract it into a custom Hook (a function starting with "use").
Bad - Hook in regular function:
function getWindowWidth() {
const [width, setWidth] = useState(window.innerWidth); // ❌ Error!
return width;
}Good - Custom Hook:
function useWindowWidth() {
const [width, setWidth] = useState(window.innerWidth); // ✓ Correct
useEffect(() => {
const handleResize = () => setWidth(window.innerWidth);
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return width;
}
// Usage in component
function MyComponent() {
const width = useWindowWidth();
return <div>Width: {width}</div>;
}Use the official ESLint plugin to catch Hook rule violations during development:
npm install eslint-plugin-react-hooks --save-devAdd to your .eslintrc configuration:
{
"plugins": ["react-hooks"],
"rules": {
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn"
}
}This will show errors in your editor when you violate Hook rules, catching issues before runtime.
Component vs. Function Naming: React determines if a function is a component by its name. Component names must start with a capital letter (e.g., MyComponent), while custom Hooks must start with "use" (e.g., useCustomHook). Regular helper functions should use lowercase. If you name a component with a lowercase letter, React may not recognize it as a component and Hook calls inside it will fail.
Webpack Module Resolution: In complex build setups with webpack, you might have duplicate React modules even if your package.json is correct. Use webpack's resolve.alias to force a single React instance:
// webpack.config.js
module.exports = {
resolve: {
alias: {
react: path.resolve('./node_modules/react'),
'react-dom': path.resolve('./node_modules/react-dom')
}
}
};Testing Environments: This error can appear in test files when using Jest or other testing frameworks. Ensure your test setup correctly mocks React and doesn't create multiple instances. Use the same React version in your test dependencies as in your application dependencies.
Server Components (Next.js 13+): In Next.js App Router with React Server Components, you cannot use Hooks in Server Components at all. Add "use client" directive at the top of files that need Hooks. This is a different constraint from the Hook rules but can produce similar error messages.
Performance Implications: While it might be tempting to conditionally call Hooks to optimize performance, this breaks React's state tracking. Instead, always call the Hook but conditionally use its result, or conditionally execute effects inside useEffect's callback function.
Debugging Tips: When the error message doesn't clearly indicate where the violation occurred, add console.logs at the start of your components to identify which component is rendering when the error happens. React DevTools' component stack trace can also help pinpoint the problematic component.
Prop spreading could cause security issues
Prop spreading could cause security issues
Error: error:0308010C:digital envelope routines::unsupported
Error: error:0308010C:digital envelope routines::unsupported
React Hook "useEffect" is called conditionally. React Hooks must be called in the exact same order in every component render.
React Hook useEffect placed inside a condition
Hook can only be called inside the body of a function component
Hook can only be called inside the body of a function component
Rollup failed to resolve import during build
How to fix "Rollup failed to resolve import" in React