Introduction
In modern React development, writing clean, reusable, and maintainable code is essential. As applications grow, you may notice repeated logic across components—such as fetching API data, handling forms, or managing window events. This is where Custom Hooks in React become extremely powerful.
Custom Hooks allow you to extract and reuse logic across multiple components, making your code cleaner and easier to scale. In this article, you will learn what custom hooks are, why they are important, and how to create one step-by-step using a real-world example.
This guide uses simple, practical language so beginners can follow along while still offering best practices for experienced developers.
What is a Custom Hook in React?
A Custom Hook is simply a JavaScript function that uses React hooks like useState, useEffect, or others to share reusable logic.
👉 Important Rule:
Custom Hook name must always start with "use"
Examples:
useFetchData
useForm
useWindowSize
Custom hooks do not change how React works—they just help you organize and reuse logic better.
Why Use Custom Hooks?
Reusability
Instead of writing the same logic again and again, you can reuse it across components.
Clean Code Structure
Components stay focused on UI, while logic moves into hooks.
Better Readability
Your code becomes easier to understand and maintain.
Scalability
As your app grows, custom hooks help manage complexity efficiently.
Real-World Problem Example
Imagine you are building a dashboard where multiple components need to fetch API data.
Without a custom hook:
Each component repeats fetch logic
Hard to maintain
More chances of bugs
Solution:
👉 Create a reusable custom hook for API fetching
Step-by-Step: Create a Custom Hook
Let’s build a custom hook called useFetch that fetches data from an API.
Step 1: Create a Custom Hook File
Create a new file:
// useFetch.js
import { useState, useEffect } from "react";
const useFetch = (url) => {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error("Failed to fetch data");
}
const result = await response.json();
setData(result);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
fetchData();
}, [url]);
return { data, loading, error };
};
export default useFetch;

Join the conversation! Your thoughts help the community grow.