JAVASCRIPT
Creating a Custom Data Fetching Hook
Build a reusable custom React hook for data fetching that encapsulates loading, error, and data states, simplifying data management in components.
import React, { useState, useEffect } from 'react';
function useFetch(url) {
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);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const result = await response.json();
setData(result);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
fetchData();
}, [url]); // Re-run effect if URL changes
return { data, loading, error };
}
function UserDataDisplay() {
const { data, loading, error } = useFetch('https://jsonplaceholder.typicode.com/users/1');
if (loading) return <p>Loading user data...</p>;
if (error) return <p style={{ color: 'red' }}>Error: {error}</p>;
if (!data) return <p>No user data found.</p>;
return (
<div>
<h1>User Profile</h1>
<p>Name: {data.name}</p>
<p>Email: {data.email}</p>
<p>Phone: {data.phone}</p>
<p>Website: {data.website}</p>
</div>
);
}
export default UserDataDisplay;
How it works: Custom hooks allow you to extract component logic into reusable functions. This `useFetch` hook encapsulates the entire data fetching process: managing `data`, `loading`, and `error` states. It uses `useEffect` to perform the fetch operation when the component mounts or when the `url` dependency changes. By separating this logic, components become cleaner, focusing solely on rendering, while the data fetching complexity is handled within the reusable hook.