React Hooks (Part-4) — Building Custom Hooks

React Hooks (Part-4) — Building Custom Hooks

Table of contents

No heading

No headings in the article.

Hey, fellow developers! 🤘 It’s Omkar, the front-end dev guy, back again with another exciting addition to my React Hook series. 🔥 This time, we’re diving deep into custom hooks! Yes, you heard it right. Custom hooks — the power tool to write reusable, modular, and efficient code. 💪 But before we begin, make sure you check out the previous parts of the series to catch up. Ready to level up your React game? Let’s do this! 💻🚀

Custom hooks are an incredibly useful feature in React that allow you to encapsulate complex logic and share it across components. With custom hooks, you can extract common functionality into reusable code, making your code-base more modular and easier to maintain.

“A simple way to think about custom hooks is that they allow you to extract the logic that generates the values you want to display in your React components, and return those values directly from the hook instead of constructing JSX elements. This makes your code more reusable and easier to maintain.”

Best way to learn this is by building the custom hooks!! Let’s look at the following example, you have to update the user favorite color from the database every-time it changes.

import { useState, useEffect } from 'react';

const useFavoriteColor = () => {
  const [favoriteColor, setFavoriteColor] = useState('');

  useEffect(() => {
    // This is where you would fetch the user's favorite color 
    // from your database and update the state with the result.
    setFavoriteColor('blue');
  }, []);

  return favoriteColor;
};

export default useFavoriteColor;

This is our useFavriateColor.js file. By naming the file with use as suffix will help to understand that this is a custom hook. This custom hook useFavoriteColor returns the user's favorite color (in this case, 'blue') by fetching it from a database. You can use this hook in any React component to get the user's favorite color without having to repeat the fetching logic. Of course, you would need to modify the hook to fetch the user's actual favorite color from your database instead of hard coded it to 'blue'.

Now lets see how to use this is in an component,

import useFavoriteColor from './useFavoriteColor';

const UserProfile = () => {
  const favoriteColor = useFavoriteColor();

  return (
    <div>
      <h1>User Profile</h1>
      <p>Favorite Color: {favoriteColor}</p>
    </div>
  );
};

export default UserProfile;

In this example, we are importing the useFavoriteColor hook and using it to get the user's favorite color. We then display the favorite color in the component's JSX by rendering the favoriteColor variable.

Note that since the useFavoriteColor hook fetches data asynchronously, it's important to handle the case where the data is not yet available. One way to do this is by using a loading state or a placeholder value.

This one is the simple and small example. Let’s have a one more simple example in which we will build a hook for fetching a random title for blog.

import { useState, useEffect } from 'react';

const useRandomPostTitle = () => {
  const [postTitle, setPostTitle] = useState('');

  const randomTitles = [
    'The Art of Coding',
    '5 Ways to Boost Your Productivity Today',
    'The Power of Community in Tech',
    'Why Learning a New Language is Good for Your Brain',
    'The Future of Artificial Intelligence',
  ];

  useEffect(() => {
    const randomIndex = Math.floor(Math.random() * randomTitles.length);
    setPostTitle(randomTitles[randomIndex]);
  }, []);

  return postTitle;
};

export default useRandomPostTitle;

This custom hook useRandomPostTitle generates a random post title from a predefined list of titles. It uses the useEffect hook to set the postTitle state to a random title when the component is first mounted.

You can use this custom hook in any React component to display a random post title:

import useRandomPostTitle from './useRandomPostTitle';

const BlogPost = () => {
  const postTitle = useRandomPostTitle();

  return (
    <div>
      <h1>{postTitle}</h1>
      <p>This is a sample blog post. Lorem ipsum dolor sit amet...</p>
    </div>
  );
};

export default BlogPost;

In this example, we are using the useRandomPostTitle hook to display a random post title in the component's JSX. We render the postTitle variable in an h1 tag, and then include some sample content for the blog post.

Now let’s build a complex custom hook for filtering the data from the url.

import { useState, useEffect } from 'react';

const useFilteredData = (url, filterValue) => {
  const [data, setData] = useState([]);
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchData = async () => {
      setIsLoading(true);

      try {
        const response = await fetch(url);
        const result = await response.json();

        // Filter the data based on the filter value
        const filteredData = result.filter(item =>
          item.name.toLowerCase().includes(filterValue.toLowerCase())
        );

        setData(filteredData);
      } catch (error) {
        setError(error);
      } finally {
        setIsLoading(false);
      }
    };

    fetchData();
  }, [url, filterValue]);

  return {
    data,
    isLoading,
    error
  };
};

export default useFilteredData;

This custom hook useFilteredData takes in two parameters: url and filterValue. The url parameter is the URL of the API endpoint to fetch data from, and the filterValue parameter is the value to use for filtering the data. It returns an object with three values: data, isLoading, and error. The data value is an array of filtered data, isLoading is a boolean indicating whether the data is currently being fetched, and error is any error that occurred during the fetch.

You can use this custom hook in any React component to fetch and filter data from an external API:

import useFilteredData from './useFilteredData';

const FilteredData = ({ filterValue }) => {
  const url = 'https://api.example.com/data';
  const { data, isLoading, error } = useFilteredData(url, filterValue);

  if (isLoading) {
    return <p>Loading...</p>;
  }

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

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

export default FilteredData;

We are using the useFilteredData hook to fetch and filter data from an external API based on the filterValue prop passed to the component. We render a loading message if the data is currently being fetched, an error message if there was an error during the fetch, and a list of filtered data if the fetch was successful.

Thank you for taking the time to read this article on custom hooks in React! I hope you found it informative and helpful in your development journey.

Custom hooks are an exciting and powerful feature of React that can take your code to the next level. By encapsulating complex behavior and making it reusable across multiple components, you can write more modular, maintainable, and scalable code.

In this article, we’ve explored some examples of custom hooks, ranging from a simple counter to a more complex data fetching system. We’ve seen how these hooks can be used to create reusable and flexible code, and we’ve discussed some best practices for creating your own custom hooks.

Whether you’re a beginner or an experienced React developer, custom hooks are a valuable tool that can help you write better code and increase your productivity. So, thank you again for reading, and happy coding!

Follow me on:
LinkedIn — https://linkedin.com/in/joshiomkar04
Twitter
https://twitter.com/ye_joshya