April 6, 2024

Hook rules in React

In React, Hooks have strict rules you must follow to ensure components behave consistently and predictably. These rules help React track the state and lifecycle of each component properly.


🧠 The Two Main Rules of Hooks

βœ… Rule #1: Only Call Hooks at the Top Level

  • Never call Hooks inside loops, conditions, or nested functions.
  • Always call them at the top level of your component or custom Hook.

Why?
React relies on the order of Hook calls between renders. Calling them conditionally would break the order, causing bugs.

🧱 Example – βœ… Correct:

function MyComponent() {
  const [count, setCount] = useState(0); // βœ… OK
  useEffect(() => {
    // βœ… OK
  }, []);
}

❌ Wrong:

function MyComponent({ isVisible }) {
  if (isVisible) {
    const [count, setCount] = useState(0); // ❌ Don't do this!
  }
}

βœ… Rule #2: Only Call Hooks from React Functions

You can only call Hooks from:

  • Function components
  • Custom Hooks

❌ Don’t call Hooks from:

  • Regular JavaScript functions
  • Class components
  • Event handlers or callbacks (directly)

🧱 Example – βœ… Correct:

function useCustomHook() {
  const [value, setValue] = useState(0);
}

function MyComponent() {
  useCustomHook(); // βœ… OK
}

❌ Wrong:

function doSomething() {
  useState(0); // ❌ Don't call here
}

πŸ§ͺ Bonus: ESLint Plugin for Enforcing Rules

React provides an official ESLint plugin:

npm install eslint-plugin-react-hooks --save-dev

In your ESLint config:

{
  "plugins": ["react-hooks"],
  "rules": {
    "react-hooks/rules-of-hooks": "error",      // βœ… Enforce Rules
    "react-hooks/exhaustive-deps": "warn"       // βœ… Check dependencies in useEffect
  }
}

πŸ“Œ Summary

RuleDescription
🧭 Call Hooks only at top levelDon’t call inside loops, conditions, or nested blocks
πŸ” Call Hooks only in React functionsUse inside function components or custom hooks only
πŸ›‘ Use ESLint pluginHelps you catch rule violations early