Skip to main content

suspense

Overview​

Reference: <Suspence>

<Suspense> lets you display a fallback until its children have finished loading.

<Suspense fallback={<Loading />}>
<SomeComponent />
</Suspense>
warning

Only Suspense-enabled data sources will activate the Suspense component. They include:

  • Data fetching with Suspense-enabled frameworks like Relay and Next.js
  • Lazy-loading component code with lazy
  • Reading the value of a cached Promise with use

Why suspense?​

Suspense-enabled framework (in Next.js)​

import Albums from "@/components/Albums";
import Loading from "@/components/Loading";
import { Suspense } from "react";

export default function Home() {
return (
<main>
<Suspense fallback={<Loading />}>
<Albums />
</Suspense>
</main>
);
}

Full example in CodeSandbox

With lazy()​

import { Suspense, lazy } from "react";
import Loading from "./Loading";
import "./styles.css";

const Albums3 = lazy(() => delayForDemo(import("./Albums3.js")));

export default function App() {
const albums = getAlbums();
return (
<div className="App">
<h1>Albums by lazy</h1>
<Suspense fallback={<Loading />}>
<Albums3 albums={albums} />
</Suspense>
</div>
);
}

// Add a fixed delay so you can see the loading state
function delayForDemo(promise) {
return new Promise((resolve) => {
setTimeout(resolve, 5000);
}).then(() => promise);
}

Full example in CodeSandbox

Cached Promise with use​

There are two ways to adopt use api:

Option 1: use cached promise​

info

Since use is an api rather than hook. That's the reason we need a cached promise to avoid recreating a promise on each render.

import { Suspense } from "react";
import Albums from "./Albums";
import Loading from "./Loading";
import "./styles.css";

export default function App() {
return (
<div className="App">
<h1>Albums by cached promise</h1>
<Suspense fallback={<Loading />}>
<Albums />
</Suspense>
</div>
);
}

Option 2: use promise as props​

import { Suspense } from "react";
import Albums2 from "./Albums2";
import { getAlbums } from "./api";
import Loading from "./Loading";
import "./styles.css";

export default function App() {
const albums = getAlbums(); // do not await here
return (
<div className="App">
<h1>Albums by promise as props</h1>
<Suspense fallback={<Loading />}>
<Albums2 albums={albums} />
</Suspense>
</div>
);
}

Full example in CodeSandbox