← Back to Chapters

React Hooks

⚛️ React Hooks

? Quick Overview

Hooks are special functions introduced in React 16.8 that let you use state and other React features without writing a class. They make functional components powerful and easier to maintain by providing lifecycle and state management features directly inside them.

React provides several built-in hooks — the most common are useState, useEffect, and useRef. Hooks also enable developers to build custom reusable logic for cleaner, modular code that can be shared across components.

? Key Concepts

? Why Hooks?

  • ✅ Simplify code by removing the need for classes.
  • ✅ Enable reuse of stateful logic between components.
  • ✅ Improve readability and separation of concerns.
  • ✅ Provide functional access to lifecycle events.

? Core Hook Categories

  • State Hooks: Manage data inside components (useState).
  • Effect Hooks: Handle side effects like fetching, timers, or subscriptions (useEffect).
  • Ref Hooks: Access or modify DOM elements directly (useRef).
  • Memoization Hooks: Optimize performance (useMemo, useCallback).
  • Context Hooks: Manage global shared state (useContext).
  • Reducer Hooks: Manage complex logic (useReducer).

? Syntax & Theory – Rules of Hooks

  1. Hooks must be called at the top level of your component (not inside loops or conditions).
  2. Hooks must be called only inside React functions — not in regular JavaScript functions.
  3. Hooks should always follow consistent naming and start with "use".
? View Code Example
// ✅ Correct: hook used at the top level of the component
function Example() {
  const [count, setCount] = React.useState(0);
}

// ❌ Incorrect: do NOT call hooks inside conditionals
if (true) {
  const [count, setCount] = React.useState(0);
}

? Core Hooks – Code Examples

1️⃣ useState – Managing Component State

Use useState to store and update local state (like a counter value).

? View Code Example
import React, { useState } from "react";

// Simple counter component using useState
function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div className="text-center">
      <h4>Count: {count}</h4>
      <button
        className="btn btn-primary me-2"
        onClick={() => setCount(count + 1)}
      >
        +
      </button>
      <button
        className="btn btn-secondary"
        onClick={() => setCount(0)}
      >
        Reset
      </button>
    </div>
  );
}

export default Counter;

2️⃣ useEffect – Performing Side Effects

Use useEffect to run side effects like timers, API calls, or subscriptions.

? View Code Example
import React, { useState, useEffect } from "react";

// Timer that increases every second using useEffect
function Timer() {
  const [time, setTime] = useState(0);

  useEffect(() => {
    const interval = setInterval(() => {
      setTime((t) => t + 1);
    }, 1000);

    return () => {
      clearInterval(interval);
    };
  }, []);

  return <p>Time Elapsed: {time}s</p>;
}

export default Timer;

3️⃣ useRef – Accessing DOM Elements

Use useRef when you want to directly access DOM elements or store mutable values.

? View Code Example
import React, { useRef } from "react";

// Focus an input element using useRef
function FocusInput() {
  const inputRef = useRef(null);

  const handleFocus = () => {
    if (inputRef.current) {
      inputRef.current.focus();
    }
  };

  return (
    <div>
      <input
        ref={inputRef}
        placeholder="Type something..."
        className="form-control mb-2"
      />
      <button
        className="btn btn-success"
        onClick={handleFocus}
      >
        Focus Input
      </button>
    </div>
  );
}

export default FocusInput;

? Live Output & Explanation

? What These Components Do

  • Counter (useState): Renders a count value and two buttons. Clicking + increments the count, and Reset sets it back to 0.
  • Timer (useEffect): Starts a timer when the component mounts and updates the time every second. When the component unmounts, the interval is cleaned up.
  • FocusInput (useRef): Stores a reference to an input element. When the button is clicked, the input is programmatically focused.

Together, these examples show how useState, useEffect, and useRef work to manage state, side effects, and DOM access in React functional components.

? Hook Comparison Table

Hook Purpose Runs On
useState Manage local component state Every re-render when state changes
useEffect Run side effects (fetch, timer, etc.) After render
useRef Access DOM nodes or persist values Does not trigger re-render
useContext Access shared data from Context Whenever context value changes
useReducer Manage complex state transitions When an action is dispatched

? Additional Core Hooks & Use Cases

  • useContext: Access global data provided by React Context (e.g., theme, auth user).
  • useReducer: Handle complex state logic with reducers (similar to Redux-style patterns).
  • useMemo: Cache expensive computations so they are not recalculated on every render.
  • useCallback: Memoize callback functions to avoid unnecessary re-creations.
  • useLayoutEffect: Similar to useEffect but runs synchronously after all DOM mutations.
  • useId: Generate stable unique IDs (React 18+) useful for accessibility and form fields.

? Tips & Best Practices

  • Combine hooks — for example, use useEffect with useState for dynamic updates.
  • Keep logic modular: extract reusable functionality into custom hooks.
  • Use useRef to store values that persist across renders without triggering re-renders.
  • Always clean up effects (like timers or event listeners) inside useEffect return functions.
  • Name custom hooks starting with use so they follow React’s conventions.

? Try It Yourself

  1. Create a simple counter using useState (with increment, decrement, and reset).
  2. Add a timer using useEffect that updates every second and stops when a button is clicked.
  3. Use useRef to focus an input field automatically on load or on a button click.
  4. Experiment with combining useState and useEffect to track online/offline status using the window online/offline events.
  5. Build a small app that uses useContext for theme switching and useReducer for managing a to-do list.

Goal: Understand the purpose and use of React’s core hooks to manage state, handle side effects, and interact with the DOM effectively within functional components.