javascript 35 lines · 8 steps

How a data-fetching hook works in React

A custom React hook fetches a user by id and cancels stale requests when the id changes.

Explained by highlit
1import { useState, useEffect } from "react";
2 
3export function useUser(userId) {
4 const [user, setUser] = useState(null);
5 const [error, setError] = useState(null);
6 const [loading, setLoading] = useState(false);
7 
8 useEffect(() => {
9 if (!userId) return;
10 
11 const controller = new AbortController();
12 
13 setLoading(true);
14 setError(null);
15 
16 fetch(`/api/users/${userId}`, { signal: controller.signal })
17 .then((res) => {
18 if (!res.ok) throw new Error(`Request failed: ${res.status}`);
19 return res.json();
20 })
21 .then((data) => {
22 setUser(data);
23 setLoading(false);
24 })
25 .catch((err) => {
26 if (err.name === "AbortError") return;
27 setError(err);
28 setLoading(false);
29 });
30 
31 return () => controller.abort();
32 }, [userId]);
33 
34 return { user, error, loading };
35}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Tracking user, error, and loading separately gives callers everything they need to render each state.
  2. 2An AbortController plus an effect cleanup prevents stale responses from overwriting fresh state.
  3. 3Returning the request state as a plain object makes the hook reusable across any component.

Related explainers

Share this explainer

Here's the card — post it anywhere.

How a data-fetching hook works in React — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code