This content originally appeared on DEV Community and was authored by Safal Bhandari
When developing a React application, you’ll often find yourself repeating the same logic across different components—whether it’s fetching data, handling form inputs, or managing timers. This is where custom hooks shine.
Custom hooks let you extract reusable logic into a function, keeping your components clean and making your code more maintainable. Let’s break this down with a practical example: fetching a list of todos.
The Problem: Fetching Data Inside a Component
Normally, you might fetch data directly inside a component using useEffect
and useState
. For instance:
useEffect(() => {
axios.get("https://dummyjson.com/todos").then((res) => {
setTodos(res.data.todos);
});
}, []);
This works perfectly fine if only one component needs this logic. But what if multiple components need to fetch todos?
You’d end up copying the same code again and again, which violates the DRY (Don’t Repeat Yourself) principle and makes maintenance harder.
The Solution: Creating a Custom Hook
Instead of repeating ourselves, we can abstract the fetching logic into a custom hook.
import { useEffect, useState } from "react";
import axios from "axios";
function useTodos() {
const [todos, setTodos] = useState([]);
useEffect(() => {
axios.get("https://dummyjson.com/todos").then((res) => {
setTodos(res.data.todos);
});
}, []);
return todos;
}
Here’s what’s happening:
-
useTodos
is just a function, but by following React’s hook rules, it can useuseState
anduseEffect
. - It encapsulates the data-fetching logic and exposes only the result (
todos
) to the component. - Any component can now import
useTodos
and instantly gain access to the todos without worrying about how they’re fetched.
Using the Custom Hook in a Component
Now your component becomes much simpler:
function App() {
const todos = useTodos();
return (
<>
{todos.map((todo) => (
<Track todo={todo} key={todo.id} />
))}
</>
);
}
Notice how App
no longer cares about fetching data. Its only job is to display todos.
Benefits of Using a Custom Hook
Reusability
You can now useuseTodos
in multiple components without repeating the same fetching code.Separation of Concerns
Components focus on rendering, while the custom hook manages the business logic (fetching).Cleaner Code
Your components become easier to read and maintain since they aren’t cluttered with logic that doesn’t belong to the UI layer.Testability
Hooks can be tested independently from UI components, making your application more robust.
Final Thoughts
Custom hooks are one of the most powerful features of React. They help you encapsulate logic, avoid duplication, and keep components focused on presentation. In our case, instead of mixing fetching logic with rendering logic in App
, we built a dedicated useTodos
hook.
The next time you see repetitive useEffect
and useState
code across your project, consider whether that logic could live inside a custom hook. Chances are, your future self will thank you.
This content originally appeared on DEV Community and was authored by Safal Bhandari