JAVASCRIPT
Create a Reusable useFetch Hook for Data Fetching
Develop a custom React useFetch hook to manage asynchronous data fetching, providing loading, error, and data states for cleaner component logic.
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(() => {
const fetchData = 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);
}
};
fetchData();
}, [url, JSON.stringify(options)]); // Dependency on options ensures refetch if they change
return { data, loading, error };
}
// Example Usage:
// function UserProfile({ userId }) {
// const { data, loading, error } = useFetch(`https://api.example.com/users/${userId}`);
// if (loading) return <p>Loading user profile...</p>;
// if (error) return <p>Error: {error.message}</p>;
// if (!data) return <p>No user data found.</p>;
// return (
// <div>
// <h2>{data.name}</h2>
// <p>Email: {data.email}</p>
// </div>
// );
// }
How it works: This `useFetch` hook provides a robust and reusable way to handle asynchronous data fetching in React components. It manages three states: `loading` (true while fetching), `error` (holds any error that occurred), and `data` (the fetched result). The `useEffect` hook triggers the fetch operation when the `url` or `options` change, handling the loading, success, and error states seamlessly. This centralizes data fetching logic, making components cleaner and easier to maintain.