šŸš€ LEVEL UP TO SENIOR:Unlock 500+ Advanced Practical Challenges & Exercises.
šŸŽ“ COURSERA PARTNER:Earn professional Google, Meta, and IBM certificates to supercharge your resume.
HTML MASTER CLASS /// LEARN TAGS /// BUILD STRUCTURE /// SEMANTIC WEB /// HTML MASTER CLASS /// LEARN TAGS ///

React Hooks Intro

Learn about React Hooks Intro in this comprehensive React tutorial for frontend web development. Learn the essential rules and philosophy behind hooks to build scalable and maintainable functional components.

⚔ Total XP: 0|šŸ’» react XP: 0

Skill Matrix

UNLOCK NODES BY LEARNING NEW TAGS.

System Hub

Core logic.

Quick Quiz //

What is the primary danger of ignoring this concept?


šŸš€ LEVEL UP TO SENIOR:Unlock 500+ Advanced Practical Challenges & Exercises.
šŸŽ“ COURSERA PARTNER:Earn professional Google, Meta, and IBM certificates to supercharge your resume.

Before 2019, giving a component state or lifecycle behavior meant writing a verbose Class Component. Hooks changed that by letting plain functions 'hook into' React's features directly — but they come with a small set of strict rules that this lesson covers in depth.

1The Dark Ages

Before React 16.8, released in 2019, functional components were purely 'dumb' — they could accept props and render UI, but they had no way to hold state or hook into lifecycle methods. Any component that needed state was forced into a verbose Class Component with a constructor, this.state, and manual method binding.

That verbosity wasn't a stylistic choice; it was the only option available before Hooks existed.

āœ•
—
+
// The old way (Class)
class App extends React.Component { ... }

// The new way (Hooks)
function App() { ... }
localhost:3000

Class Components

The old paradigm.

2The Problem with Classes

Class Components had three major recurring flaws: the this keyword confused beginners and required manual binding in constructors, lifecycle methods like componentDidMount forced unrelated pieces of logic to be jammed together into a single method, and sharing stateful logic between components was incredibly difficult without patterns like render props or higher-order components.

These pain points were the direct motivation for introducing Hooks.

āœ•
—
+
import { useState, useEffect } from 'react';
localhost:3000

Spaghetti Code

Tangled lifecycles.

3The Hook Revolution

React 16.8 introduced Hooks, which let functional components 'hook into' React's state and lifecycle features from entirely within a plain, clean JavaScript function — no constructors, no this, and no manual binding required.

A function component can now hold its own memory with something as simple as const [count, setCount] = useState(0), something that previously required an entire class definition.

āœ•
—
+
function App() {
  const [val, setVal] = useState(0); // āœ… Top Level

  if (condition) {
    // āŒ WRONG: useState(10);
  }
}
localhost:3000

The Revolution

Functions level up.

4What are Hooks?

At their core, Hooks are just regular JavaScript functions imported from the react library, like import { useState, useEffect } from 'react'. They give ordinary UI functions superpowers — useState for memory, useEffect for side effects — that a plain function couldn't otherwise have.

There's nothing magical happening syntactically; a Hook is just a function call that React recognizes and treats specially internally.

āœ•
—
+
// āœ… React Component
function MyComp() { useHook(); }

// āŒ Regular JS function
function utils() { useHook(); }
localhost:3000

Imports

Grabbing the tools.

5The

By convention and strict rule, every Hook name must start with the word use — useState, useEffect, useAuthUser, and so on. This isn't just a style preference; it's what allows React's linter tooling to automatically detect Hook calls and enforce the Rules of Hooks.

A function named getState() or fetchData() that internally calls other Hooks won't be recognized as a Hook itself, so the linter can't verify it's being used correctly — which is exactly why the use prefix is mandatory rather than optional.

āœ•
—
+
const { data } = useMyCustomDataFetcher();
localhost:3000
localhost:3000/concept-5
UI Rendered Successfully
React Component Preview

6Rule #1: Top Level Only

Hooks must only be called at the top level of a React function — never inside loops, conditions like if statements, or nested functions. A Hook call has to be unconditional, meaning it runs on every single render, no exceptions.

Writing if (isOnline) { useState(null) } is a fatal error precisely because it makes the Hook conditional, even though the code looks harmless at a glance.

āœ•
—
+
// Stable Hook Order = Predictable App
localhost:3000

Rule #1

Top Level Only.

7Why Top Level?

React enforces the top-level rule because it tracks Hook state internally by the exact order Hooks are called in, not by name. Each useState or useEffect call corresponds to a specific position in an internal array, like index 0, 1, 2, and so on.

If a Hook is skipped on one render because it sat inside a conditional that turned false, every subsequent Hook call shifts down one slot in that internal array, and React ends up reading the wrong stored value for each one — silently corrupting the component's state.

āœ•
—
+
<h1>Hook Expert!</h1>
localhost:3000

The Engine

Call Order Matters.

8Under the Hood: A Linked List

Internally, React attaches a linked list of 'memory cells' to each component instance (technically its Fiber node). Every Hook call reads or writes the next cell in that list, advancing an internal cursor — the 'array index' framing is a simplification of the real data structure, but the consequence is identical: skip a Hook conditionally, and every later Hook call reads the wrong cell.

āœ•
—
+
// Simplified mental model
fiber.memoizedState = cell0 -> cell1 -> cell2 -> ...
localhost:3000

The Real Data Structure

A linked list per component.

9The ESLint Plugin Catches Violations

The official eslint-plugin-react-hooks package ships two rules: 'rules-of-hooks', which flags conditional or out-of-order Hook calls at build time, and 'exhaustive-deps', which flags missing dependencies in useEffect, useMemo, and useCallback. Both rules only work because every Hook name starts with use, which is exactly what lets the linter recognize a Hook call in the first place.

āœ•
—
+
// eslint-plugin-react-hooks catches this automatically:
if (isOnline) {
  useState(null); // React Hook "useState" is called conditionally
localhost:3000

Lint Error

Caught before runtime.

10A Catalog of Built-in Hooks

React ships several built-in Hooks, each solving a distinct problem: useState holds a single piece of memory, useEffect synchronizes with something outside React, useContext reads a value from a Provider above without prop drilling, useRef holds a mutable value that never triggers a re-render, useReducer centralizes complex state transitions, and useMemo/useCallback memoize a value or function to preserve reference identity across renders.

āœ•
—
+
useState()    // memory
useEffect()   // sync with the outside world
useContext()  // read shared data
useRef()      // mutable, non-rendering value
useReducer()  // complex state transitions
localhost:3000

The Toolbox

Each hook, one job.

11Step-by-Step Breakdown

The Dark Ages. Before React 16.8 (released in 2019), Functional Components were 'dumb'. They couldn't hold state or use lifecycle methods. If you needed state, you were forced to write verbose Class Components.

The Problem with Classes. Classes had three major flaws: 1) The 'this' keyword confused beginners. 2) Lifecycle methods (componentDidMount) forced unrelated logic to be grouped together. 3) Sharing logic between components was incredibly difficult.

The Hook Revolution. In React 16.8, Hooks were introduced. Hooks allow Functional Components to 'hook into' React state and lifecycle features from entirely within a simple, clean Javascript function.

What are Hooks?. At their core, Hooks are just regular Javascript functions imported from the 'react' library. They give your UI functions superpowers like memory (useState) and the ability to cause side effects (useEffect).

The 'use' Prefix. By convention and strict rule, every single Hook must start with the word 'use'. This prefix allows React's linter tools to automatically check for bugs and enforce the Rules of Hooks.

Which of the following function names indicates to the React Linter that it is a Hook?

  • →getAuthenticationData()
  • →useAuthenticationData()

Rule #1: Top Level Only. CRITICAL: You must only call Hooks at the TOP LEVEL of your React function. Never call them inside loops, conditions (if statements), or nested functions. They must be unconditional.

Why Top Level?. Why this strict rule? Because React tracks Hook state by the *order* they are called. If a Hook is inside an if statement that suddenly becomes false, a Hook is skipped. This completely ruins the array index React uses internally, breaking the app.

Can you call useState or useEffect inside a for loop or an if statement?

  • →Yes, as long as the condition never changes
  • →No, they must always be at the top level

Under the Hood: A Linked List. Internally, React attaches a linked list of 'memory cells' to each component instance (technically its Fiber node). Every Hook call reads or writes the next cell in that list, advancing an internal cursor. The 'array index' idea is a simplification — the real data structure is a linked list — but the consequence is identical: skip a Hook conditionally, and every later Hook reads the wrong cell.

The ESLint Plugin Catches Violations. You rarely have to remember the Rules of Hooks by pure discipline — the official eslint-plugin-react-hooks package ships two rules: 'rules-of-hooks', which flags conditional or out-of-order Hook calls at build time, and 'exhaustive-deps', which flags missing dependencies in useEffect, useMemo, and useCallback. Both rules only work because every Hook name starts with 'use', which is exactly what lets the linter recognize a Hook call in the first place.

Rule #2: React Functions Only. Rule #2: Only call Hooks from inside React Function Components, or from inside Custom Hooks. You cannot call them from regular utility Javascript functions.

Is it valid to call a Hook inside a standard Javascript helper function like formatDate(date)?

  • →Yes, hooks can run anywhere in JS
  • →No, hooks only work inside React components

A Catalog of Built-in Hooks. React ships several built-in Hooks, each solving a distinct problem: useState holds a single piece of memory; useEffect synchronizes with something outside React; useContext reads a value from a Provider above without prop drilling; useRef holds a mutable value that never triggers a re-render; useReducer centralizes complex state transitions; useMemo and useCallback memoize a value or function to preserve reference identity. Each has its own dedicated lesson ahead.

Custom Hooks. Because Hooks are just functions, you can write your own! 'Custom Hooks' are just JS functions that start with 'use' and call other hooks. This allows you to extract and reuse complex stateful logic effortlessly.

The Death of 'this'. Thanks to Hooks, you will almost never need to write a Class Component or use the this keyword in modern React. The community has fully embraced Functional Components.

A Predictable App. By strictly following the Rules of Hooks, you ensure that React's engine can predictably preserve your state between every single re-render of the DOM.

Hook Expert. Brilliant! You've learned the fundamental rules of modern React. You understand why we abandoned classes and the strict rules required to use Hooks properly. Let's dive deeper!

Level Up šŸš€

Advanced cheat sheets, SEO tricks, and interview prep for this topic.

Browser Support

ChromeSupported

Fully supported.

FirefoxSupported

Fully supported.

SafariSupported

Fully supported.

EdgeSupported

Fully supported.

Accessibility (A11y)

1Hooks Don't Change What Markup a Component Renders

Whether a component is written as a class or with Hooks has no bearing on accessibility — the underlying JSX still needs semantic elements, labels, and ARIA attributes exactly as before; Hooks only change how state and side effects are organized in the source code.

2Effect-Driven Focus Management Still Needs Explicit Handling

If a `useEffect` opens a modal or navigates the user to new content, the effect should also explicitly move keyboard focus to that content — React doesn't do this automatically just because state changed.

SEO Implications

  • 1

    Hooks Are a Client-Side Implementation Detail Invisible to Crawlers

    Whether a component is built with Hooks or as a legacy class has zero effect on the HTML a search engine sees — Hooks affect component internals, not the rendered markup structure or its SEO value.

  • 2

    Custom Hooks Encourage Consistent Data-Fetching Patterns Across Pages

    Extracting fetch logic into a shared custom Hook like `useArticleData()` makes it easier to guarantee that every page using it renders the same critical metadata and content consistently, reducing accidental inconsistencies that could hurt indexing.

Best Practices

Extract Repeated Stateful Logic Into a Custom Hook

If multiple components need the same combination of `useState` and `useEffect` logic — like tracking window width or a data fetch — wrap it in a custom Hook (a function starting with `use`) instead of duplicating the logic in each component.

Never Call Hooks Conditionally, Even for 'Obviously Safe' Conditions

Even if a condition never changes at runtime, wrapping a Hook call in an `if` statement or early return breaks React's ability to reliably track Hook order — always call every Hook unconditionally at the top of the function.

Frequent Bugs

THE BUG

React throws 'Rendered more hooks than during the previous render' after adding a conditional around a Hook call.

THE FIX

A Hook was placed inside an `if` statement or after an early return, so it wasn't called on every render. Move all Hook calls to the unconditional top level of the component, and put any conditional logic inside the Hook itself instead.

THE BUG

Calling a custom function that internally uses useState throws 'Invalid hook call' when used outside a component.

THE FIX

Hooks — including custom Hooks — can only be called from the body of a React function component or from another custom Hook, never from a plain JavaScript utility function. Rename the function to start with `use` only if it's genuinely meant to be called from a component.

Real-World Examples

A Custom Hook for Tracking Window Width

Instead of duplicating a resize event listener and useState pair in every component that needs the viewport width, a single useWindowWidth custom Hook centralizes that logic and can be reused anywhere.

function useWindowWidth() {
  const [width, setWidth] = useState(window.innerWidth);
  useEffect(() => {
    const handler = () => setWidth(window.innerWidth);
    window.addEventListener('resize', handler);
    return () => window.removeEventListener('resize', handler);
  }, []);
  return width;
}

Interview Prep

?Frequently Asked Questions

Pascual Vila

Pascual Vila

Frontend Instructor // Code Syllabus

Common Pitfalls & Errors

The Error //

Mutating State Directly

// Wrong const [user, setUser] = useState({ name: 'Alice' }); user.name = 'Bob'; // React won't re-render // Correct setUser({ ...user, name: 'Bob' });

The Solution //

Never mutate a state variable directly (e.g., state.count = 1). Always use the setter function provided by useState to ensure the component re-renders.

The Error //

Missing 'key' prop in lists

// Wrong {items.map(item => <li>{item.name}</li>)} // Correct {items.map(item => <li key={item.id}>{item.name}</li>)}

The Solution //

When rendering a list of elements using .map(), always provide a unique 'key' prop to the outermost element to help React identify which items have changed.

Lesson Glossary

[01]Hook

A function that lets you use React features in functional components.

Code Preview
use...

[02]Functional Component

A plain JS function that returns JSX.

Code Preview
function App() { ... }

[03]Top Level Rule

Hooks must be called at the very top of a function.

Code Preview
No loops/ifs

[04]Custom Hook

A JS function whose name starts with 'use' and calls other hooks.

Code Preview
useAuth()

[05]Stateful Logic

Code that manages data changes and lifecycle events.

Code Preview
Logic reuse

[06]React Engine

The internal system that tracks hook order and values.

Code Preview
Under the hood

[07]Fiber Node

React's internal representation of a component instance, which holds the linked list of that component's Hook memory cells.

Code Preview
fiber.memoizedState

[08]eslint-plugin-react-hooks

The official ESLint plugin that enforces the Rules of Hooks and flags missing dependency array entries.

Code Preview
rules-of-hooks

Continue Learning