Hooks Pattern in react
Tags: react, javascript, webdev, designpatterns
Published: 2023-11-18 17:13:01

> With the introduction of hooks in React 16.8, hooks gained popularity.

Let's create a hook for making API calls in React. This will help encapsulate the logic related to fetching data from an API, making it reusable across different components.

### Problem: Repeated API Call Logic

Suppose you have multiple components in your React application that need to make API calls. Repeating the same logic for making API calls in each component can lead to code duplication and reduced maintainability.

#### Step 1: Problem Code

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

const ComponentWithApiCall = () => {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await fetch('https://api.example.com/data');
        const result = await response.json();
        setData(result);
      } catch (error) {
        setError(error);
      } finally {
        setLoading(false);
      }
    };

    fetchData();
  }, []);

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

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

  return <p>Data: {data}</p>;
};
```

### Solution: Creating a Custom Hook for API Calls

Let's create a custom hook called `useApiCall` to handle the API call logic. This will make it easy to reuse this logic across different components.

#### Step 2: Solution Code

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

// Custom hook for making API calls
const useApiCall = (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);
        const result = await response.json();
        setData(result);
      } catch (error) {
        setError(error);
      } finally {
        setLoading(false);
      }
    };

    fetchData();
  }, [url]); // Dependency array ensures that the effect runs when 'url' changes

  return { data, loading, error };
};

// Using the custom hook in a component
const ComponentWithApiCall = () => {
  const { data, loading, error } = useApiCall('https://api.example.com/data');

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

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

  return <p>Data: {data}</p>;
};
```

#### Step-by-Step Explanation:

1. **Create the Custom Hook (`useApiCall`):**
   ```jsx
   const useApiCall = (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);
           const result = await response.json();
           setData(result);
         } catch (error) {
           setError(error);
         } finally {
           setLoading(false);
         }
       };

       fetchData();
     }, [url]);

     return { data, loading, error };
   };
   ```
   The `useApiCall` custom hook encapsulates the logic for making API calls. It returns an object containing the data, loading state, and error state.

2. **Use the Custom Hook in the Component:**
   ```jsx
   const { data, loading, error } = useApiCall('https://api.example.com/data');
   ```
   Use the custom hook in the component by providing the API URL. The hook returns the necessary states for handling the API call.

By creating a custom hook for API calls, we've modularized and abstracted away the logic related to fetching data. This makes it easy to reuse the logic in different components, enhancing code maintainability and reusability.

> "Your feedback and ideas are invaluable – drop a comment, and let's make this even better!"

😍 If you enjoy the content, please 👍 like, 🔄 share, and 👣 follow for more updates!
Join me on a professional journey through my LinkedIn profile: [Linkedin Profile](https://www.linkedin.com/in/kurmivivek295/)