DeveloperBreeze

Custom Hook: useFetch

import { useState, useEffect } from 'react';

function useFetch(url, options = {}) {
    const [data, setData] = useState(null);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState(null);

    useEffect(() => {
        let isMounted = true; // Track if component is mounted

        const fetchData = async () => {
            setLoading(true);
            try {
                const response = await fetch(url, options);
                if (!response.ok) {
                    throw new Error('Network response was not ok');
                }
                const result = await response.json();
                if (isMounted) {
                    setData(result);
                }
            } catch (error) {
                if (isMounted) {
                    setError(error);
                }
            } finally {
                if (isMounted) {
                    setLoading(false);
                }
            }
        };

        fetchData();

        return () => {
            isMounted = false; // Cleanup to avoid setting state on unmounted component
        };
    }, [url, options]);

    return { data, loading, error };
}

export default useFetch;

Using the Custom Hook

Here’s an example of how to use the useFetch hook in a React component to fetch and display data.

import React from 'react';
import useFetch from './useFetch'; // Ensure correct import path

function UserList() {
    const { data, loading, error } = useFetch('https://jsonplaceholder.typicode.com/users');

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

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

export default UserList;

Features and Benefits

  • Reusability: The useFetch hook can be used across different components and applications, reducing code duplication and simplifying API interaction.
  • Loading and Error States: Automatically manages loading and error states, providing a consistent way to handle asynchronous operations.
  • Cleanup Handling: Prevents state updates on unmounted components, reducing potential memory leaks and ensuring stability.

Customization and Extension

  • Custom Headers: Extend the hook to accept custom headers or authentication tokens in the options parameter.
  • Polling: Implement a polling mechanism by setting up a setInterval within the useEffect for periodically fetching data.
  • Data Transformation: Add a callback function to transform the fetched data before setting it in state.

Continue Reading

Handpicked posts just for you — based on your current read.

Integrating Flowbite with Tailwind CSS: A Step-by-Step Tutorial

   <!-- src/index.html -->

   <!DOCTYPE html>
   <html lang="en">
   <head>
     <meta charset="UTF-8">
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <title>Tailwind CSS with Flowbite</title>
     <link rel="stylesheet" href="output.css"> <!-- Link to the built CSS file -->
   </head>
   <body>
     <!-- Example Flowbite Button -->
     <button data-modal-target="authentication-modal" data-modal-toggle="authentication-modal" class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center" type="button">
       Toggle Modal
     </button>

     <!-- Flowbite Modal Component -->
     <div id="authentication-modal" tabindex="-1" aria-hidden="true" class="hidden overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 w-full md:inset-0 h-modal md:h-full">
       <div class="relative p-4 w-full max-w-md h-full md:h-auto">
         <!-- Modal content -->
         <div class="relative bg-white rounded-lg shadow dark:bg-gray-700">
           <button type="button" class="absolute top-3 right-2.5 text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm p-1.5 ml-auto inline-flex items-center dark:hover:bg-gray-800 dark:hover:text-white" data-modal-hide="authentication-modal">
             <svg aria-hidden="true" class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
               <path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"></path>
             </svg>
             <span class="sr-only">Close modal</span>
           </button>
           <div class="py-6 px-6 lg:px-8">
             <h3 class="mb-4 text-xl font-medium text-gray-900 dark:text-white">Sign in to our platform</h3>
             <form class="space-y-6" action="#">
               <div>
                 <label for="email" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Your email</label>
                 <input type="email" name="email" id="email" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:placeholder-gray-400 dark:text-white" placeholder="name@company.com" required>
               </div>
               <div>
                 <label for="password" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Your password</label>
                 <input type="password" name="password" id="password" placeholder="••••••••" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:placeholder-gray-400 dark:text-white" required>
               </div>
               <button type="submit" class="w-full text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">Sign in</button>
             </form>
           </div>
         </div>
       </div>
     </div>

     <script src="https://unpkg.com/flowbite@1.6.5/dist/flowbite.js"></script>
   </body>
   </html>

Explanation:

Oct 24, 2024 Article

Getting Started with Axios in JavaScript

This tutorial provides a comprehensive introduction to using Axios for making HTTP requests in JavaScript. By understanding these basics, you'll be able to integrate Axios into your applications, streamlining your API interactions and improving your development workflow.

Sep 02, 2024 Tutorial

Discussion 0

Please sign in to join the discussion.

No comments yet. Start the discussion!