Rules of Hooks in React: Beginner’s Guide with Examples

Hooks are a powerful feature in React that allow functional components to have state, side effects, refs, and memoization.

However, hooks have strict rules to ensure React can track state and updates reliably.

Breaking these rules can lead to bugs, unexpected behavior, or errors like:

 
Error: Hooks can only be called inside the body of a function component.

Let’s understand these rules clearly.

Rule 1: Only Call Hooks at the Top Level

  • Do not call Hooks inside loops, conditions, or nested functions.

  • Always call Hooks at the top level of your component.

 Wrong Example:

 
function MyComponent() {
if (true) {
const [count, setCount] = useState(0); //  Do not call inside condition
} }

 Correct Example:

 
function MyComponent() {
const [count, setCount] = useState(0); //  Always at top level
if (count > 0) {
console.log("Count is positive");
} }

Rule 2: Only Call Hooks from React Functions

  • Hooks can only be called inside:

    1. React functional components

    2. Custom hooks

Wrong Example:

 
function notAComponent() {
const [count, setCount] = useState(0); //  Not a component or custom hook
}

 Correct Example:

 
function MyComponent() {
const [count, setCount] = useState(0); //  Functional component
}

Or inside a custom hook:

 
function useCounter() {
const [count, setCount] = useState(0); //  Custom hook
return { count, setCount };
}

Rule 3: Name Custom Hooks Starting with “use”

  • Custom hooks must start with use to follow React convention.

  • This allows React to recognize them as hooks.

Example:

 
function useFetchData(url) { // ✅ Custom hook }
  • Avoid names like fetchDataHook — React will not treat it as a hook.

Rule 4: Hooks Must Be Called in the Same Order

  • React relies on hook order to preserve state across renders.

  • Never call a hook conditionally or inside a loop.

 Wrong Example:

 
function Component({ flag }) {
if (flag) {
const [count, setCount] = useState(0); //  Conditional hook
} }

 Correct Example:

 
function Component({ flag }) {
const [count, setCount] = useState(0); //  Always called
if (flag) { console.log("Flag is true");
} }

Common Built-in Hooks

  • useState → state in functional components

  • useEffect → side effects

  • useContext → global state / shared data

  • useRef → DOM access or persisting values

  • useMemo → memoize expensive calculations

  • useReducer → advanced state management

Follow the rules above when using all these hooks.

Best Practices

RuleExplanation
Call Hooks at top levelNever inside loops, conditions, or nested functions
Only from components or custom hooksAvoid calling hooks in normal JS functions
Custom hooks start with “use”Ensures React recognizes them as hooks
Maintain hook orderAlways call hooks in the same sequence across renders
Keep logic simpleCombine hooks logically and split complex logic into custom hooks

FAQ

Q1: Can I call hooks inside if or loops?
 No. Always call hooks at the top level.

Q2: Can hooks be used in class components?
 No. Hooks only work in functional components.

Q3: Why must custom hooks start with use?
 React uses the naming convention to identify hooks and preserve state correctly.