Mahamudul Hasan Rubel
HomeBlogCoursesAboutProjectsSkillsExperiencePhotosContact
Mahamudul Hasan Rubel

Senior Software Engineer crafting high-performance web applications and SaaS platforms.

Navigation

  • Home
  • Blog
  • Courses
  • About
  • Projects
  • Skills
  • Experience
  • Photos
  • Contact

Get in Touch

Available for senior/lead roles and consulting.

bd.mhrubel@gmail.comHire Me

© 2026 Mahamudul Hasan Rubel. All rights reserved.

Built with using Next.js 16 & Tailwind v4

Back to Blog
Lesson 32 of the React Fundamentals: Build Modern UIs from Scratch course
ReactJune 25, 20263 min read

Extracting Custom Hooks: A Guide to React Reusability

Learn to create custom hooks in React to abstract complex data-fetching logic. Improve your code reusability and simplify your components by building a useFetch.

reacthookscustom-hooksrefactoringjavascriptweb-developmentfrontend

Previously in this course, we explored Folder Structure Best Practices to organize our project. Now that our movie-browser app is growing, you've likely noticed that our data-fetching logic—the useState and useEffect patterns we mastered in Handling Loading States in React and Managing Errors—is starting to clutter our components.

It’s time to solve this by creating custom hooks.

The Problem: Logic Bloat

When you fetch data in multiple components, you find yourself rewriting the same boilerplate: declaring data, loading, and error states, plus the useEffect block to trigger the fetch.

Not only does this lead to repetitive code, but it also makes your components harder to read. If you decide to change how you handle errors or add a loading timeout, you’d have to hunt down every instance of that logic throughout your app. Abstraction allows us to pull this shared behavior into a single, reusable function.

From First Principles: What is a Custom Hook?

A custom hook is simply a JavaScript function that starts with the word use and calls other React hooks.

Think of it as a "logic container." It doesn't return JSX; instead, it returns the values or functions that your component needs to render its UI. By moving our data-fetching logic into a custom hook, we treat that logic as a black box: the component asks for data, and the hook provides it.

Worked Example: Creating useFetch

Let’s move our movie-fetching logic into a dedicated file. Create a new file at src/hooks/useFetch.js.

JAVASCRIPT
import { useState, useEffect } from CE9178">'react';

export function useFetch(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchData = async () => {
      try {
        setLoading(true);
        const response = await fetch(url);
        if (!response.ok) throw new Error(CE9178">'Failed to fetch');
        const json = await response.json();
        setData(json);
      } catch (err) {
        setError(err.message);
      } finally {
        setLoading(false);
      }
    };

    fetchData();
  }, [url]);

  return { data, loading, error };
}

Now, look at how much cleaner your main component becomes. Instead of ten lines of state and effects, you have one:

JAVASCRIPT
import { useFetch } from CE9178">'./hooks/useFetch';

function MovieList() {
  const { data, loading, error } = useFetch(CE9178">'https://api.example.com/movies');

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error: {error}</p>;

  return <ul>{data.map(movie => <li key={movie.id}>{movie.title}</li>)}</ul>;
}

Hands-on Exercise

Refactor your existing movie-browser search logic.

  1. Create a useFetch hook that accepts a url.
  2. Import useFetch into your App.jsx.
  3. Replace your manual useEffect and useState calls in App.jsx with the return values from your new hook.
  4. Ensure the UI still renders correctly.

Common Pitfalls

  • Forgetting the use prefix: React relies on the use naming convention to identify hooks. If you name your function fetchData instead of useFetch, React will throw an error when you try to call other hooks inside it.
  • Over-abstracting: Don't turn every single line of logic into a hook. Only extract code that you actually reuse in at least two places, or logic that is so complex it obscures the purpose of your component.
  • Missing Dependencies: Just like in a standard useEffect, if your custom hook uses variables inside its effect, make sure those variables are included in the dependency array (or passed as arguments to the hook).

Recap

Custom hooks are the primary tool for reusability in modern React. By extracting stateful logic, you keep your components focused on the UI, while your hooks handle the "how" of data management. This separation of concerns makes your codebase significantly easier to test and maintain.

Up next: We'll tackle Prop Drilling and Context API to share data across our component tree without passing props through every single level.

Previous lessonFolder Structure Best PracticesNext lesson Prop Drilling and Context API
Back to Blog

Similar Posts

ReactJune 25, 20264 min read

Introduction to Side Effects: Managing External Logic in React

Learn why side effects like API calls belong in the useEffect hook. Distinguish between rendering and side effects to build predictable React applications.

Read more
ReactJune 26, 20263 min read

Refactoring for Scalability: Professionalizing Your React Architecture

Learn to master scalability through expert refactoring techniques. We'll extract reusable UI, optimize folder structures, and decouple logic for cleaner code.

Part of the course

React Fundamentals: Build Modern UIs from Scratch

beginner · Lesson 32 of 49

  1. 1

    Introduction to Component-Based Architecture

    4 min
  2. 2

    Understanding the Virtual DOM

    4 min
  3. 3

    Setting Up with Vite

    3 min
Read more
ReactJune 26, 20263 min read

Protected Routes for Authenticated Views in React

Learn to implement protected routes in your React application. We'll show you how to guard dashboard pages and redirect unauthenticated users securely.

Read more
4

Mastering JSX Syntax

4 min
  • 5

    Creating Static Components

    3 min
  • 6

    Styling Components

    3 min
  • 7

    Passing Data with Props

    3 min
  • 8

    Dynamic Movie Cards

    3 min
  • 9

    Component Composition

    3 min
  • 10

    Conditional Rendering

    3 min
  • 11

    Rendering Lists of Data

    4 min
  • 12

    The Key Prop Explained

    4 min
  • 13

    Introduction to React State

    4 min
  • 14

    Managing State with useState

    3 min
  • 15

    Building an Interactive Search Bar

    3 min
  • 16

    Handling Click Events

    4 min
  • 17

    Updating State Based on Previous State

    4 min
  • 18

    Filtering the Movie List

    3 min
  • 19

    Handling Form Submissions

    3 min
  • 20

    Controlled Components

    4 min
  • 21

    Event Bubbling and Propagation

    3 min
  • 22

    Building a Movie Filter Toggle

    3 min
  • 23

    Introduction to Side Effects

    4 min
  • 24

    useEffect Dependencies

    4 min
  • 25

    Fetching Data from an API

    3 min
  • 26

    Handling Loading States

    3 min
  • 27

    Managing Errors

    3 min
  • 28

    Cleanup Functions in useEffect

    3 min
  • 29

    Debouncing Search Input

    3 min
  • 30

    Refactoring for Clean Code

    3 min
  • 31

    Folder Structure Best Practices

    4 min
  • 32

    Extracting Custom Hooks

    3 min
  • 33

    Prop Drilling and Context API

    3 min
  • 34

    Polishing the UI

    3 min
  • 35

    Finalizing the Movie Browser

    3 min
  • 36

    Review of Component Lifecycle

    4 min
  • 37

    Review of State Management

    4 min
  • 38

    Building a Modal Component

    3 min
  • 39

    Introduction to PropTypes

    3 min
  • 40

    Performance Optimization Basics

    3 min
  • 41

    Handling Browser History

    3 min
  • 42

    Working with LocalStorage

    3 min
  • 43

    Building a Favorites List

    3 min
  • 44

    Handling Media in React

    3 min
  • 45

    Introduction to Testing

    4 min
  • 46

    Debugging React Apps

    4 min
  • 47

    Deployment Basics

    3 min
  • 48

    Using External Libraries

    3 min
  • 49

    Advanced

    3 min
  • View full course