Popular Searches
Popular Course Categories
Popular Courses

Introduction to React Hooks

Introduction to React Hooks

React Hooks Fundamentals

Introduction to React Hooks

React Hooks are special functions that allow developers to use React features such as state, effects, context, references, and reusable logic inside function components. Hooks make it easier to build interactive user interfaces without writing class components.

React introduced Hooks in React 16.8. Common examples include useState(), useEffect(), useContext(), and useRef(). Read the official React Hooks documentation.

Course link: JustAcademy React JS Training Course | Register for React JS Course Demo


1. Learning Objectives

  • Understand what React Hooks are and why they are used.
  • Learn how Hooks work in function components.
  • Understand the purpose of commonly used built-in Hooks.
  • Manage component state with useState().
  • Perform side effects with useEffect().
  • Share data using useContext().
  • Access DOM elements and store mutable values with useRef().
  • Understand the Rules of Hooks and create custom Hooks.

2. What Are React Hooks?

React Hooks are functions provided by React that let function components use React features. They help developers manage component state, synchronize with external systems, access context, and reuse stateful logic.

Example Without Hooks: Simple Function Component

function Welcome() {
  return <h1>Welcome to React JS!</h1>;
}

export default Welcome;

This component displays a heading but does not need state or other Hooks.

Example With a Hook

import { useState } from 'react';

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

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

export default Counter;

Explanation: The useState() Hook stores the counter value. When the button is clicked, setCount() updates the state, and React renders the updated count.


3. Why Were React Hooks Introduced?

Before Hooks, developers commonly used class components to manage state and lifecycle-related behavior. Hooks made many of these tasks possible in function components and provided a way to reuse stateful logic across components.

  • Simpler components: Manage state without class syntax.
  • Reusable logic: Extract common behavior into custom Hooks.
  • State management: Store and update changing data.
  • Effect handling: Synchronize components with browser APIs, subscriptions, and other external systems.
  • Better organization: Group related logic together instead of spreading it across class lifecycle methods.
  • Improved maintainability: Build reusable functions for common application behavior.

4. How Do React Hooks Work?

Hooks are called while React renders a function component or a custom Hook. React preserves the relevant state and associates Hook calls with the component across renders. When state changes, React can render the component again with the updated value.

Basic Workflow

  1. The component renders.
  2. A Hook reads state or prepares behavior for the component.
  3. The user interacts with the interface or an external event occurs.
  4. A state setter may update the stored state.
  5. React renders the component again when necessary.
  6. The user sees the updated interface.

Example

import { useState } from 'react';

function LikeButton() {
  const [likes, setLikes] = useState(0);

  return (
    <button onClick={() => setLikes(previousLikes => previousLikes + 1)}>
      Likes: {likes}
    </button>
  );
}

export default LikeButton;

The functional updater receives the previous state and returns the next state. This is useful when the new value depends on the previous value.


5. Commonly Used React Hooks

Hook Purpose Common Example
useState() Stores component state. Counter, form inputs, toggle buttons.
useEffect() Synchronizes with external systems. Event listeners, subscriptions, browser APIs.
useContext() Reads context from a provider. Theme, locale, shared user information.
useRef() Stores a mutable reference without causing a re-render when it changes. DOM access, timer identifiers.
useReducer() Manages state using a reducer function. Complex state transitions.
useMemo() Caches a calculation result between renders when dependencies remain unchanged. Expensive derived calculations.
useCallback() Caches a function definition between renders when dependencies remain unchanged. Passing callbacks to optimized child components.
useId() Generates IDs useful for accessibility relationships. Connecting labels and input descriptions.
Custom Hooks Reuse stateful or effect-related logic. Window size, online status, reusable form behavior.

These Hooks serve different purposes. Use the simplest Hook that fits the problem; performance Hooks such as useMemo() and useCallback() are optimizations, not requirements for every component.


6. useState() Hook

The useState() Hook lets a function component store and update state. It returns an array containing the current state value and a setter function.

Syntax

const [state, setState] = useState(initialValue);
  • state: the current value.
  • setState: the function used to request a state update.
  • initialValue: the initial state value.

Example: Counter

import { useState } from 'react';

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

  function increaseCount() {
    setCount(previousCount => previousCount + 1);
  }

  function decreaseCount() {
    setCount(previousCount => previousCount - 1);
  }

  return (
    <div>
      <h2>Counter: {count}</h2>
      <button onClick={increaseCount}>Increase</button>
      <button onClick={decreaseCount}>Decrease</button>
    </div>
  );
}

export default Counter;

Important Points

  • State can hold strings, numbers, Booleans, arrays, objects, and other values.
  • Updating state requests a re-render when React determines the state has changed.
  • Do not directly mutate objects or arrays stored in state; create updated copies.
  • Use a functional updater when the next state depends on the previous state.

7. useEffect() Hook

The useEffect() Hook synchronizes a component with an external system. Examples include browser event listeners, subscriptions, timers, and third-party widgets. It can also be used for data fetching when a suitable framework or data-fetching solution is not being used.

Syntax

useEffect(() => {
  // Set up or synchronize with an external system.

  return () => {
    // Clean up when necessary.
  };
}, [dependencies]);

Example: Updating the Browser Tab Title

import { useEffect, useState } from 'react';

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

  useEffect(() => {
    document.title = `Count: ${count}`;
  }, [count]);

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

export default CounterTitle;

When count changes, the Effect updates the browser tab title.

Understanding Dependencies

Dependency Pattern Meaning
useEffect(() => {...}) Runs after every commit in which the component renders.
useEffect(() => {...}, []) Runs its setup after the initial mount; development Strict Mode may perform an extra setup-and-cleanup cycle.
useEffect(() => {...}, [value]) Runs after the initial mount and again when the dependency changes.

Important: Every reactive value used by an Effect must be handled correctly in its dependency list. Return a cleanup function when setup creates a subscription, listener, timer, or other resource that needs to be released. Effects are not needed for every calculation or event handler.


8. useContext() Hook

The useContext() Hook reads a value from a React context. It helps share information with deeply nested components without passing the same props through every intermediate component.

Example: Theme Context

import { createContext, useContext } from 'react';

const ThemeContext = createContext('light');

function ThemeMessage() {
  const theme = useContext(ThemeContext);

  return <p>Current theme: {theme}</p>;
}

function App() {
  return (
    <ThemeContext value="dark">
      <ThemeMessage />
    </ThemeContext>
  );
}

export default App;

In modern React, a context object can be used as a provider as shown above. In React versions before React 19, use . The component reads the nearest provider's value.

Common Uses

  • Theme preferences.
  • Language and localization settings.
  • Shared authentication or user information.
  • Application-wide configuration.

9. useRef() Hook

The useRef() Hook stores a mutable value that remains available between renders. Updating its current property does not itself trigger a re-render. Refs can also point to DOM elements.

Example: Focusing an Input

import { useRef } from 'react';

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

  function handleFocus() {
    inputRef.current?.focus();
  }

  return (
    <div>
      <input ref={inputRef} placeholder="Enter your name" />
      <button onClick={handleFocus}>Focus Input</button>
    </div>
  );
}

export default FocusInput;

When the button is clicked, the input receives focus through its DOM reference.

Common Uses

  • Focusing or selecting DOM elements.
  • Storing timer IDs or other mutable values.
  • Keeping a value between renders when changing it should not update the UI.

10. useReducer() Hook

The useReducer() Hook is useful when state transitions are more complex or when multiple actions update the same state. It uses a reducer function that receives the current state and an action, then returns the next state.

Syntax

const [state, dispatch] = useReducer(reducer, initialState);

Example: Counter Using useReducer

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 };
    case 'reset':
      return { count: 0 };
    default:
      return state;
  }
}

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

  return (
    <div>
      <h2>Count: {state.count}</h2>
      <button onClick={() => dispatch({ type: 'increment' })}>+</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
      <button onClick={() => dispatch({ type: 'reset' })}>Reset</button>
    </div>
  );
}

export default Counter;

dispatch() sends an action to the reducer, which determines the next state.


11. useMemo() and useCallback()

11.1 useMemo()

useMemo() caches the result of a calculation between renders while its dependencies remain unchanged. It can help avoid repeated expensive calculations.

import { useMemo, useState } from 'react';

function PriceCalculator() {
  const [price, setPrice] = useState(100);
  const [quantity, setQuantity] = useState(1);

  const total = useMemo(() => {
    return price * quantity;
  }, [price, quantity]);

  return (
    <div>
      <p>Total: {total}</p>
      <button onClick={() => setQuantity(q => q + 1)}>
        Add One Item
      </button>
    </div>
  );
}

11.2 useCallback()

useCallback() caches a function definition between renders while its dependencies remain unchanged. It is especially useful when passing callbacks to memoized child components or when a stable function reference is needed.

import { useCallback, useState } from 'react';

function SearchExample() {
  const [query, setQuery] = useState('');

  const clearQuery = useCallback(() => {
    setQuery('');
  }, []);

  return (
    <div>
      <input
        value={query}
        onChange={event => setQuery(event.target.value)}
      />
      <button onClick={clearQuery}>Clear</button>
    </div>
  );
}

Neither Hook should be added automatically to every component. Use them when caching provides a meaningful benefit or is needed for a particular optimization.


12. What Are Custom Hooks?

A custom Hook is a JavaScript function whose name starts with use and that can call other Hooks. Custom Hooks let developers reuse stateful logic across multiple components without duplicating the same implementation.

Example: Custom Counter Hook

import { useState } from 'react';

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

  function increment() {
    setCount(previousCount => previousCount + 1);
  }

  function decrement() {
    setCount(previousCount => previousCount - 1);
  }

  function reset() {
    setCount(initialValue);
  }

  return { count, increment, decrement, reset };
}

export default useCounter;

Using the Custom Hook

import useCounter from './useCounter';

function Counter() {
  const { count, increment, decrement, reset } = useCounter(0);

  return (
    <div>
      <h2>Count: {count}</h2>
      <button onClick={increment}>Increase</button>
      <button onClick={decrement}>Decrease</button>
      <button onClick={reset}>Reset</button>
    </div>
  );
}

export default Counter;

Each component calling this custom Hook gets its own independent state unless the Hook explicitly connects to shared state or an external store.


13. Rules of React Hooks

React Hooks must follow specific rules so React can correctly preserve state and other Hook behavior between renders.

  1. Call Hooks at the top level: Do not call Hooks inside loops, conditions, nested functions, or try/catch/finally blocks.
  2. Call Hooks from React functions: Call Hooks from function components or custom Hooks, not ordinary JavaScript functions.
  3. Keep Hook calls in a consistent order: Do not skip Hook calls based on conditions.
  4. Use meaningful custom Hook names: Custom Hook names should start with use.
  5. Follow dependency rules: For Effects and memoization Hooks, specify reactive dependencies correctly.
  6. Do not mutate state directly: Use the appropriate state setter or reducer dispatch.

Incorrect Example

function Example({ enabled }) {
  if (enabled) {
    const [count, setCount] = useState(0);
  }

  return <div>Example</div>;
}

Correct Example

function Example({ enabled }) {
  const [count, setCount] = useState(0);

  if (!enabled) {
    return <div>Disabled</div>;
  }

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

Call the Hook before the conditional return so it is called in the same order on every render.


14. React Hooks vs. Class Components

Feature Function Components with Hooks Class Components
State Managed with Hooks such as useState() and useReducer(). Commonly managed with this.state.
Lifecycle behavior Effects synchronize with external systems. Lifecycle methods such as componentDidMount() and componentWillUnmount().
Reusable logic Custom Hooks can share stateful logic. Often uses other patterns, such as higher-order components or render props.
Syntax JavaScript functions. JavaScript classes.
New development Commonly preferred for modern React components. Still supported; existing class components do not need to be rewritten immediately.

15. Common Mistakes When Using Hooks

Mistake Why It Is a Problem Solution
Calling a Hook inside a condition Hook call order may change between renders. Move the Hook to the top level.
Calling Hooks in regular functions React cannot manage them as component or custom Hook calls. Call Hooks only in function components or custom Hooks.
Mutating state directly React may not detect the intended change. Create new objects or arrays and use the setter.
Incorrect Effect dependencies The Effect may use outdated values or run too often. Include all required reactive dependencies and review the Effect logic.
Using Effects for simple calculations Can create unnecessary state and extra rendering. Calculate values during rendering when appropriate.
Overusing useMemo or useCallback Adds complexity without always improving performance. Optimize when there is a clear reason.
Forgetting cleanup Listeners, timers, or subscriptions may remain active unnecessarily. Return a cleanup function when required.

16. Mini Project: Interactive Profile Card

Objective: Build a profile card that uses React Hooks to update a person's name, toggle profile details, and change the theme.

Complete Code

import { useState } from 'react';

function ProfileCard() {
  const [name, setName] = useState('Alex');
  const [showDetails, setShowDetails] = useState(false);
  const [darkMode, setDarkMode] = useState(false);

  const cardStyle = {
    padding: '20px',
    borderRadius: '8px',
    backgroundColor: darkMode ? '#222' : '#f2f2f2',
    color: darkMode ? '#fff' : '#222'
  };

  return (
    <div style={cardStyle}>
      <h2>Profile Card</h2>

      <label htmlFor="profile-name">Name:</label>
      <input
        id="profile-name"
        value={name}
        onChange={event => setName(event.target.value)}
      />

      <h3>Hello, {name || 'Guest'}!</h3>

      <button onClick={() => setShowDetails(value => !value)}>
        {showDetails ? 'Hide Details' : 'Show Details'}
      </button>

      {showDetails && (
        <p>This profile card demonstrates React state and conditional rendering.</p>
      )}

      <button onClick={() => setDarkMode(value => !value)}>
        {darkMode ? 'Switch to Light Mode' : 'Switch to Dark Mode'}
      </button>
    </div>
  );
}

export default ProfileCard;

Hooks Used

  • useState() manages the name, details visibility, and theme.
  • State updates trigger rendering of the changed interface.
  • Conditional rendering displays or hides the profile details.
  • The theme state determines the card's inline styles.

17. Interview Questions and Answers

Q1. What are React Hooks?

React Hooks are functions that allow function components to use React features such as state, effects, context, and refs.

Q2. Why are Hooks used in React?

Hooks simplify state management in function components and allow developers to reuse stateful logic through custom Hooks.

Q3. What is useState()?

useState() declares a state variable and returns its current value and a setter function.

Q4. What is useEffect()?

useEffect() synchronizes a component with external systems, such as subscriptions, browser APIs, or timers.

Q5. What is useContext()?

useContext() reads a context value from the closest matching provider above the component.

Q6. What is useRef()?

useRef() stores a mutable value between renders or provides a reference to a DOM element without triggering a re-render when its current value changes.

Q7. What is a custom Hook?

A custom Hook is a function whose name starts with use and that combines Hooks to reuse logic across components.

Q8. Can Hooks be used inside class components?

No. Hooks are used in function components and custom Hooks, not directly inside class components.

Q9. Why must Hooks be called at the top level?

React relies on a consistent order of Hook calls to associate state and other Hook data with the correct component.

Q10. What is the difference between useMemo() and useCallback()?

useMemo() caches a calculation result, while useCallback() caches a function definition.

Q11. What is useReducer()?

useReducer() manages state through a reducer function and dispatched actions, making complex state transitions easier to organize.

Q12. Do all React components need Hooks?

No. Components that only display information may not need Hooks. Use Hooks when a component needs state, effects, context, refs, or other Hook-supported functionality.


18. Practice Exercises

  1. Create a counter with Increase, Decrease, and Reset buttons using useState().
  2. Create a form that stores a name and email in state.
  3. Use useEffect() to update the browser tab title when a counter changes.
  4. Build a theme switcher using useContext().
  5. Use useRef() to focus an input field when a button is clicked.
  6. Create a to-do list using useState().
  7. Manage multiple counter actions using useReducer().
  8. Use useMemo() to cache an expensive calculation when needed.
  9. Create a custom Hook that manages a counter or reusable form logic.
  10. Build a profile card with editable information and conditional details.

19. Revision Checklist

  • Understand the definition and purpose of React Hooks.
  • Know why Hooks are useful in function components.
  • Understand useState() and state updates.
  • Understand useEffect(), dependencies, and cleanup.
  • Know how useContext() shares values.
  • Know how useRef() stores mutable values and references DOM elements.
  • Understand when useReducer() is useful.
  • Understand the difference between useMemo() and useCallback().
  • Know how to create and use custom Hooks.
  • Follow the Rules of Hooks.
  • Practice building small React projects using Hooks.

20. Additional Learning Resources


Conclusion

React Hooks make it possible to use state, effects, context, refs, and reusable logic in function components. Start with useState() and useEffect(), then learn useContext(), useRef(), useReducer(), performance Hooks, and custom Hooks. Practicing these concepts through small projects will help you build maintainable and interactive React applications.

Explore the JustAcademy React JS Training Course or register for a React JS course demo.

whatsapp