🚀 React Hooks Explained — What They Are

🚀 React Hooks Explained — What They Are

🟦 What Are React Hooks?

React Hooks are special functions used inside functional components that let you manage state, lifecycle, and other powerful features — without using class components.

🔹 Before Hooks → only class components had state & lifecycle

🔹 After Hooks → functional components became powerful


1️⃣ useState — Manage Component State

useState() helps you create a state variable and update it inside a component.

👉 Example:

import { useState } from "react";

function Counter() {
  const [count, setCount] = useState(0); // state variable

  return (
    <button onClick={() => setCount(count + 1)}>
      Count: {count}
    </button>
  );
}
        

🔹 count → current value 🔹 setCount → function to update value 🔹 Component re-renders whenever state changes


2️⃣ useEffect — Handle Side Effects

useEffect() runs side effects after the component renders.

✨ Side effects include: • API calls • Timers • Event listeners • console logs

👉 Example:

import { useEffect, useState } from "react";

function WelcomeMessage() {
  const [message, setMessage] = useState("Loading...");

  useEffect(() => {
    console.log("Component mounted!");

    setTimeout(() => {
      setMessage("Welcome to React!");
    }, 1000);
  }, []); // runs only once when component loads

  return <h1>{message}</h1>;
}        

3️⃣ useRef — Hold Value Without Re-render + Access DOM

useRef() is used to store a value that does NOT cause re-render when updated. It is also commonly used to access DOM elements directly.

✨ Why use useRef?

✔ Store values between renders ✔ Update data without re-rendering ✔ Access input, button, or any DOM element ✔ Good for timers, counters, scroll tracking, focus, etc.


✅ Example 1: Update value without re-render

import { useRef, useState } from "react";

function ClickTracker() {
  const clickCountRef = useRef(0);   // does NOT re-render component
  const [uiCount, setUiCount] = useState(0); // triggers re-render

  const handleClick = () => {
    clickCountRef.current += 1; // updates silently
    setUiCount(uiCount + 1);    // updates UI
    console.log("Ref Count:", clickCountRef.current);
  };

  return (
    <div>
      <h3>UI Count (re-renders): {uiCount}</h3>
      <h3>Ref Count (no re-render): {clickCountRef.current}</h3>
      <button onClick={handleClick}>Click Me</button>
    </div>
  );
}
        

📌 clickCountRef.current changes but the component will not re-render. 📌 uiCount changes → React re-renders.


✅ Example 2: Access DOM directly (focus input)

import { useRef } from "react";

function FocusInput() {
  const inputRef = useRef(null);

  const focusField = () => {
    inputRef.current.focus(); // Access DOM element
  };

  return (
    <div>
      <input ref={inputRef} type="text" placeholder="Type here..." />
      <button onClick={focusField}>Focus Input</button>
    </div>
  );
}
        

📌 inputRef.current gives you the DOM input element. 📌 Clicking the button focuses the input automatically.

4️⃣ useMemo — Improve Performance by Memoizing Values

useMemo() calculates a value only when its dependency changes, not on every render.

✔ Prevents expensive calculations from re-running ✔ Returns value (not a function) ✔ Good for filtering, sorting, heavy loops, derived data

import { useMemo, useState } from "react";

function PriceCalculator({ price }) {
  const [count, setCount] = useState(0);

  const total = useMemo(() => {
    console.log("Calculating total...");
    return price * 10; // expensive calculation simulated
  }, [price]); // runs only when price updates

  return (
    <div>
      <h3>Total Price: {total}</h3>
      <button onClick={() => setCount(count + 1)}>
        Re-render: {count}
      </button>
    </div>
  );
}
        

📌 useMemo prevents unnecessary recalculation 📌 useEffect runs code but does not return a computed value 📌 useMemo runs the function and returns the output


5️⃣ useCallback — Memoize Functions

useCallback() returns a memoized version of a function, so the function is recreated only when dependencies change.

✔ Good when passing functions to child components ✔ Avoids unnecessary re-renders ✔ Keeps function reference stable

import { useCallback, useState } from "react";

function Counter() {
  const [count, setCount] = useState(0);

  const increment = useCallback(() => {
    setCount((c) => c + 1);
  }, []); // same function reference every render

  return (
    <button onClick={increment}>Count: {count}</button>
  );
}
        

📌 useMemo → memoizes values 📌 useCallback → memoizes functions


6️⃣ useContext — Share Data Without Props Drilling

useContext() allows you to access global data without passing props manually at every level.

✔ Good for user info, theme, language, auth data

import { createContext, useContext } from "react";

const UserContext = createContext();

function App() {
  return (
    <UserContext.Provider value="Ragu">
      <Profile />
    </UserContext.Provider>
  );
}

function Profile() {
  const user = useContext(UserContext);
  return <h3>Hello, {user}</h3>;
}
        

📌 No need to pass props through multiple components 📌 Clean and easier global state sharing


7️⃣ useReducer — Handle Complex State

useReducer() is used when you have multiple action types or complex state updates.

✔ Better than useState for multi-step logic ✔ Works like Redux reducer

useState → simple state useReducer → complex state updates

import { useReducer } from "react";

function reducer(state, action) {
  switch (action.type) {
    case "increment":
      return { count: state.count + 1 };
    case "decrement":
      return { count: state.count - 1 };
    default:
      return state;
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, { count: 0 });

  return (
    <>
      <h3>Count: {state.count}</h3>
      <button onClick={() => dispatch({ type: "increment" })}>+</button>
      <button onClick={() => dispatch({ type: "decrement" })}>-</button>
    </>
  );
}
        

📌 Best for structured, predictable state updates


8️⃣ useLayoutEffect — Runs Before Screen Paints

useLayoutEffect() works similar to useEffect, but timing is different.

🔥 Super Simple Difference

Hook When does it run?

useEffect - After the UI is painted (async)

useLayoutEffect - Before the UI is painted (sync)

Used for: ✔ DOM measurements ✔ Layout adjustments ✔ Avoid flickering

import { useLayoutEffect, useRef } from "react";

function Box() {
  const boxRef = useRef(null);

  useLayoutEffect(() => {
    console.log("Width:", boxRef.current.offsetWidth);
  }, []);

  return <div ref={boxRef} style={{ width: "200px" }}>Box</div>;
}
        

📌 useLayoutEffect runs earlier → guarantees DOM is measured before painting

9️⃣ Custom Hooks — Reuse Your Logic Across Components

A custom hook is simply a JavaScript function that uses one or more React Hooks (useState, useEffect, etc.) and allows you to extract reusable logic from components.


✅ Why use Custom Hooks?

✔ Reuse logic across multiple components ✔ Keep components clean and small ✔ Avoid repeating useEffect / useState code ✔ Share API calls, form logic, timers, storage, etc.


⭐ Example: Custom Hook for Local Storage

This custom hook saves data to localStorage automatically.

import { useState, useEffect } from "react";

function useLocalStorage(key, initialValue) {
  const [value, setValue] = useState(
    localStorage.getItem(key) || initialValue
  );

  useEffect(() => {
    localStorage.setItem(key, value);
  }, [value, key]);

  return [value, setValue];
}

export default useLocalStorage;
        

📌 How to use it in a component?

import useLocalStorage from "./useLocalStorage";

function Profile() {
  const [name, setName] = useLocalStorage("username", "Guest");

  return (
    <>
      <h3>Hello, {name}</h3>
      <button onClick={() => setName("Ragu")}>Set Name</button>
    </>
  );
}
        

✔ Value is automatically saved ✔ No repeating useEffect logic ✔ Cleaner components

I was asked about the hooks in an interview. But I failed to answer that. Thanks for explaining it.

To view or add a comment, sign in

More articles by Raguraman P

Others also viewed

Explore content categories