[React.js] - Part 16. React Hooks - Custom Hook

Ace Lennox
19 Jan 20253 minutes to read

React Custom Hooks are a powerful way to reuse logic across multiple components. By extracting common functionality into reusable functions, you can keep your code DRY (Don’t Repeat Yourself) and maintainable. In this guide, we’ll learn how to create and use custom Hooks with easy-to-follow examples.


What Are Custom Hooks?

Custom Hooks are reusable functions in React that encapsulate component logic. They always start with the prefix use, such as useFetch, and can include state, effects, or any other Hook logic.

Why Use Custom Hooks?

  1. Reusability: Share logic between multiple components.

  2. Cleaner Code: Move complex logic out of components for better readability.

  3. Consistency: Standardize common patterns across your app.


Example 1: Fetching Data Without a Custom Hook

Here’s an example where a Home component fetches and displays data:

index.js

import { useState, useEffect } from "react";
import ReactDOM from "react-dom/client";

const Home = () => {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch("https://jsonplaceholder.typicode.com/posts")
      .then((response) => response.json())
      .then((data) => setData(data));
  }, []);

  return (
    <div>
      <h2>Posts</h2>
      {data &&
        data.map((post) => (
          <p key={post.id}>{post.title}</p>
        ))}
    </div>
  );
};

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Home />);

What’s the Issue?

If you need to fetch data in another component, you’ll have to duplicate this logic. This violates the DRY principle and makes your code harder to maintain.


Example 2: Creating a Custom Hook

We’ll extract the fetch logic into a reusable custom Hook called useFetch.

useFetch.js

import { useState, useEffect } from "react";

const useFetch = (url) => {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const fetchData = async () => {
      setLoading(true);
      try {
        const response = await fetch(url);
        const result = await response.json();
        setData(result);
      } catch (error) {
        console.error("Error fetching data:", error);
      } finally {
        setLoading(false);
      }
    };

    fetchData();
  }, [url]);

  return { data, loading };
};

export default useFetch;

Explanation

  1. Reusable Logic: The useFetch Hook takes a URL as a parameter and returns the fetched data and loading state.

  2. Async/Await: Improved readability for asynchronous operations.

  3. Error Handling: Handles errors gracefully.


Example 3: Using the Custom Hook

Now we’ll use useFetch in the Home component.

index.js

import ReactDOM from "react-dom/client";
import useFetch from "./useFetch";

const Home = () => {
  const { data, loading } = useFetch("https://jsonplaceholder.typicode.com/posts");

  if (loading) {
    return <h2>Loading...</h2>;
  }

  return (
    <div>
      <h2>Posts</h2>
      {data &&
        data.map((post) => (
          <p key={post.id}>{post.title}</p>
        ))}
    </div>
  );
};

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Home />);

Key Improvements

  1. Simpler Component: The Home component is now focused only on rendering UI.

  2. Reusable Hook: The fetch logic can now be reused in any component by simply calling useFetch.

  3. Scalability: Adding more features to the Hook (e.g., caching or error messages) will benefit all components that use it.


Benefits of Custom Hooks

  • Encapsulation: Separate logic from UI.

  • Reusability: Use the same logic across multiple components.

  • Scalability: Easily add more functionality to your Hooks.


Best Practices

  1. Prefix with use: Always start custom Hooks with use to follow React conventions.

  2. Avoid Side Effects: Keep Hooks pure and avoid side effects inside them.

  3. Document Usage: Clearly define what parameters the Hook accepts and what it returns.

  4. Test Thoroughly: Ensure your Hooks handle edge cases, like errors or loading states.


Conclusion

Custom Hooks are a powerful tool in React for organizing and reusing logic. By extracting shared logic into Hooks, you can make your components cleaner, more modular, and easier to maintain.

Try building your own custom Hooks to see how they can simplify your React projects!


Source Code

The complete source code for this part is available on GitHub


Recent Posts

Latest Posts


logo

Explore insightful articles and tutorials on programming, web development, and mobile app creation. Dive into topics like ReactJS, Next.js, Android, iOS, and modern coding practices. Learn with practical examples and tips for building robust, responsive, and high-performing applications. Perfect for developers of all levels seeking to enhance their skills.

Social

© 2025. All rights reserved