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:
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:
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;
Explanation
useState → manages data, loading, and error
useEffect → runs API call when URL changes
return → exposes values to components
Step 2: Use Custom Hook in a Component
import React from "react";
import useFetch from "./useFetch";
function Users() {
const { data, loading, error } = useFetch(
"https://jsonplaceholder.typicode.com/users"
);
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error}</p>;
return (
<div>
<h2>User List</h2>
<ul>
{data.map((user) => (
<li key={user.id}>
{user.name} - {user.email}
</li>
))}
</ul>
</div>
);
}
export default Users;
What Just Happened?
The component does not handle API logic anymore
It only focuses on displaying data
Logic is reusable across multiple components
Step 3: Reuse the Same Hook Anywhere
You can now reuse useFetch in different components:
const { data } = useFetch("https://jsonplaceholder.typicode.com/posts");
👉 Same logic, different API
Advanced Enhancement (Optional)
You can make your custom hook more powerful by adding:
Refetch functionality
const refetch = () => {
setLoading(true);
setError(null);
fetchData();
};
Abort controller (to avoid memory leaks)
Caching for better performance
Best Practices for Custom Hooks
Always start with "use"
This ensures React recognizes it as a hook.
Keep hooks focused
Each hook should solve one specific problem.
Avoid UI logic inside hooks
Hooks should handle logic, not JSX.
Use dependency arrays carefully
Incorrect dependencies can cause infinite loops.
Handle cleanup properly
Especially for API calls and subscriptions.
Common Mistakes to Avoid
Real-World Use Cases of Custom Hooks
API data fetching (useFetch)
Form handling (useForm)
Authentication (useAuth)
Window resize tracking (useWindowSize)
Dark mode toggle (useTheme)
Conclusion
Custom Hooks are one of the most powerful features in React. They help you write cleaner, reusable, and scalable code by separating logic from UI.
By learning how to create and use custom hooks, you can significantly improve your React development workflow and build better applications.
Start by creating small hooks like useFetch, and gradually move toward more advanced patterns like shared state, caching, and custom logic abstraction.