Loading, without the flags
Juggling loading and error state in every component gets repetitive. In React 19, a component can read a promise with use(); while it's pending, the nearest <Suspense> shows a fallback. Frameworks like Next.js build on exactly this.
use(promise) + <Suspense>
import { Suspense, use } from "react";
const menuPromise = new Promise((resolve) =>
setTimeout(() => resolve(["Momo", "Thukpa", "Yomari"]), 800),
);
function Menu() {
const dishes = use(menuPromise);
return <ul>{dishes.map((d) => <li key={d}>{d}</li>)}</ul>;
}
export default function App() {
return (
<Suspense fallback={<p>Loading the menu…</p>}>
<Menu />
</Suspense>
);
}- Errors from a rejected promise go to the nearest error boundary — frameworks provide these (e.g. Next.js error.js).
- lazy(() => import("./Chart")) + Suspense loads a component's code only when needed.
- Put Suspense boundaries where a loading state makes sense to the user — not around every component.