JAVASCRIPT
Simplified Data Fetching with a useFetch Hook
Create a custom React `useFetch` hook to encapsulate asynchronous data fetching, managing loading states, data, and errors, providing a clean API for component integration.
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();
// The dependency array could include 'url' and 'options' stringified if they change frequently,
// or just 'url' if options are static. For simplicity here, we assume options are stable.
}, [url]);
return { data, loading, error };
// Example Usage:
// function UserProfile({ userId }) {
// const { data: user, loading, error } = useFetch(`https://api.example.com/users/${userId}`);
// if (loading) return <div>Loading user...</div>;
// if (error) return <div>Error: {error.message}</div>;
// if (!user) return null;
// return (
// <div>
// <h2>{user.name}</h2>
// <p>Email: {user.email}</p>
// </div>
// );
// }
}
How it works: The `useFetch` hook simplifies asynchronous data fetching in React components. It manages `data`, `loading`, and `error` states, which are returned to the consuming component. Upon component mount or when the `url` changes, it initiates a fetch request. It updates the loading state before the request, sets the data upon success, or catches and sets any errors. This abstraction significantly cleans up components that need to interact with APIs.