Fetching Data with useEffect
11 min read
Loading Remote Data
The classic pattern for data fetching combines useEffect (to trigger the request) with useState for the data, loading, and error states.
jsx
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
let cancelled = false;
setLoading(true);
fetch(`/api/users/${userId}`)
.then(res => res.json())
.then(data => {
if (!cancelled) {
setUser(data);
setLoading(false);
}
})
.catch(err => {
if (!cancelled) {
setError(err.message);
setLoading(false);
}
});
return () => { cancelled = true; };
}, [userId]);
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error}</p>;
return <h2>{user?.name}</h2>;
}In production apps, prefer a data-fetching library like SWR or TanStack Query over raw useEffect. They handle caching, deduplication, revalidation, and loading states for you.
Ready to test yourself?
Practice React— quiz & coding exercises