How to Create a Custom useFetch Hook in React
Tags: react, javascript, usefetch, webdev
Published: 2023-06-10 09:01:19

## **OUTLINE**

- Introduction
- Creating a custom useFetch hook in React
- How to use the useFetch Hook in a React component
- Conclusion

---

## **Introduction**

Custom hooks are reusable functions that contain logic and can be used in functional components. A `useFetch` hook is a reusable function in React that abstracts the process of fetching data from an API, provides an efficient way to manage HTTP requests and handles the loading and error states.

In this article, we'll walk through the process of creating a custom `useFetch` hook in React. 

Let's dive in!

---

## **Creating a custom useFetch hook in React**

After setting up your react project, go to the `src` directory and create a folder called `hooks`. In this folder, create a new file called `useFetch.js` which will contain the useFetch logic.

Here is the code below:

```react
import { useState, useEffect } from 'react';

const useFetch = (url) => {
  const [data, setData] = useState(null);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
      fetch(url)
      .then(response => {
        if (!response.ok) { 
          // error coming back from server
          throw Error('could not fetch the data for that resource');
        } 
        return response.json();
      })
      .then(data => {
        setIsLoading(false);
        setData(data);
        setError(null);
      })
      .catch(err => {
        setIsLoading(false);
        setError(err.message);
      })
  }, [url])

  return { data, isLoading, error };
}
 
export default useFetch;

```

## **Code explanation**

Firstly, import the necessary dependencies inside the `useFetch.js`file. We import the `useState` and `useEffect` hooks from the 'react' library.

We declare the `useFetch` custom hook which takes a `url` parameter, which represents the API endpoint we want to fetch data from. 

We declare three state variables using the `useState` hook imported from the react library.  The `data` state variable is the fetched data and is set to null. The `isLoading` state variable indicates whether the data is currently being fetched and is set to true. The `error` state variable represents errors that could occur during the data fetching process and it is initially set to null. 

Next, we declare the `useEffect` hook which will be triggered whenever the `url` dependency changes. We define a `fetch()` function inside the `useEffect` callback and this function sends a GET request to the specified `url`. The `then` callback function is used to handle the response from the server.

We use `response.ok` to check for errors from the API and If an error is detected, an error message is thrown using the `throw` statement. And if there are no errors, the response is converted to JSON format using `response.json()`. We store the resulting data in the `setData` state variable, `isLoading` is set to false, and the `error` state variable is also set to null. 

Next, we define a `catch` callback function to handle any errors that occurred during the fetch request. The `isLoading` state variable to false, indicating that the data loading has been completed and the error message is stored in the `setError` state variable.

Finally, the `useFetch` custom hook returns an object containing the `data`, `isLoading`, and `error` state variables for components to access these values. Then we export the `useFetch` custom hook as the default export of the module so it can be imported into other files. 

---

## **How to use the useFetch Hook in a React component**

To utilize the useFetch Hook, create the functional component and import the hook into your React component.

## **Code sample**

```react
import { useFetch } from '../hooks/useFetch'

const BlogPosts = () => {

    const { data: blogs, isLoading, error } = useFetch('http://localhost:3000/blogposts');
    
    return (
      <div>
        {isLoading && <div>Loading blog posts...</div>}
        {error && <div>{error}</div>}

       {/* Render the fetched data */}

        {blogs && blogs.map((blog) => (
          <p key={blog.id}>{blog.name}</p>
        ))}
      </div>
    );
  }

export default BlogPosts;

```

In the above component, we're using the `useFetch` hook to fetch data from the `http://localhost:3000/blogposts` endpoint. The `data`, `isLoading`, and `error` state variables returned by the hook are then used to conditionally render the content. If `isLoading` is true, then a loading message will be displayed, and If an error occurs, an error message will be displayed, otherwise the fetched data will be rendered in the component.

Lastly, import the functional component `<BlogPosts />` inside the `App` component in the React project directory. 

---

## **Conclusion**

We have successfully created a `useFetch` Hook in React and utilize it in a functional component. A custom `useFetch` hook contains a data fetching logic which can be used across different components in a React project allowing us to write a clean and maintainable code.