← Back to all snippets
JAVASCRIPT

Efficient Data Fetching with useFetch Hook

A custom React hook for simplifying asynchronous data fetching, managing loading states, errors, and successful data retrieval in your components.

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

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

  const fetchData = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const response = await fetch(url, options);
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }
      const result = await response.json();
      setData(result);
    } catch (err) {
      setError(err);
    } finally {
      setLoading(false);
    }
  }, [url, options]);

  useEffect(() => {
    fetchData();
  }, [fetchData]);

  return { data, loading, error, refetch: fetchData };
};

export default useFetch;

// Example Usage:
// function MyComponent() {
//   const { data, loading, error, refetch } = useFetch('https://api.example.com/data');

//   if (loading) return <div>Loading...</div>;
//   if (error) return <div>Error: {error.message} <button onClick={refetch}>Retry</button></div>;
//   return <div>Data: {JSON.stringify(data)}</div>;
// }
How it works: This `useFetch` custom hook centralizes the logic for making API requests. It manages `loading`, `error`, and `data` states, providing a clean interface for components to consume. The `fetchData` function is memoized with `useCallback` to prevent unnecessary re-renders, and `useEffect` triggers the fetch operation when the `url` or `options` change, or on initial mount. A `refetch` function is also exposed for manual retries.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs