Model request states
A request is not just its final data. Design loading, success, empty and error states so the interface remains understandable throughout the request.
Fetch in an Effect
useEffect(() => { const controller = new AbortController(); async function loadTasks() { try { setStatus("loading"); const response = await fetch( "/api/tasks", { signal: controller.signal } ); if (!response.ok) { throw new Error( "Could not load tasks" ); } setTasks(await response.json()); setStatus("success"); } catch (error) { if (error.name !== "AbortError") { setStatus("error"); } } } loadTasks(); return () => controller.abort(); }, []);
Check response.ok; fetch does not reject merely because the server returned an HTTP error. Abort the request in cleanup so a response is not applied after the component is gone.
Application data loading
Manual fetching teaches the lifecycle, but larger applications benefit from a framework or data library that supports caching, request deduplication, navigation and server rendering. Keep transport details outside presentational components.
Read the request in stages
The Effect creates one controller for one request. Setting status to loading gives the next render something useful to show. await fetch pauses only the async function, not the browser. The response status is checked before JSON is read. Cleanup aborts the particular request created by that Effect.
The catch block distinguishes an intentional abort from a real failure. In a complete component, render a progress message for loading, a retry control for errors, an empty message for zero tasks and the list after success.
Challenge: complete the four-state interface
Build the rendering logic around the example request. Include loading, error, empty and success states. Add a Retry button without reloading the entire page.
A changing requestKey state value can deliberately trigger the request Effect, or the loading function can be extracted so both the Effect and Retry handler use it. Whichever design you choose, keep abort cleanup correct.
