One thing to remember
Every API call has three visible states: loading, success, and failure. If you only design success, your app will feel broken during normal network delays.
A reviewer on mobile data should know what is happening, what went wrong, and what they can try next.
Why this matters
In a hackathon demo, your API may be slow because the free server is waking up, the college Wi-Fi is crowded, or the reviewer is on a hotspot.
A loading message stops people from clicking again and again. A failure message shows that you handled real-world use, not just the happy path.
Handle three states
Do each one yourself, then tap it to tick it off. The ticks are only a checklist for you: they are not marked or scored.
0 of 5 done
React fetch example
This example calls your own API route and renders all three states. Use the same pattern for dashboards, lists, profile pages, or search results.
import { useEffect, useState } from "react";
export default function ProjectList() {
const [projects, setProjects] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState("");
async function loadProjects() {
setLoading(true);
setError("");
try {
const res = await fetch("/api/projects");
if (!res.ok) {
throw new Error("Could not load projects");
}
const data = await res.json();
if (!Array.isArray(data.projects)) {
throw new Error("Projects data is not in the expected format");
}
setProjects(data.projects);
} catch (err) {
setError(err.message || "Something went wrong");
} finally {
setLoading(false);
}
}
useEffect(() => {
loadProjects();
}, []);
if (loading) {
return <p>Loading projects...</p>;
}
if (error) {
return (
<div>
<p>{error}</p>
<button onClick={loadProjects}>Try again</button>
</div>
);
}
return (
<ul>
{projects.map((project) => (
<li key={project.id}>{project.name}</li>
))}
</ul>
);
}Use AI carefully
You can ask an AI tool: “Add loading, error, and retry states to this React component without changing the API path.”
Check the answer before pasting it. Make sure it does not remove your existing fields, does not invent a new endpoint, and still handles non-200 responses with res.ok.
Common weak spots
Do not show a blank page while waiting. A blank page looks like a crash.
Do not only use console.error. Reviewers cannot see your browser console during a quick demo. Put a useful message on the page.
Test failure on purpose
Do each one yourself, then tap it to tick it off. The ticks are only a checklist for you: they are not marked or scored.
0 of 5 done
Do this now
Do each one yourself, then tap it to tick it off. The ticks are only a checklist for you: they are not marked or scored.
0 of 5 done