Represent content that is still resolving
Give one asynchronous profile screen explicit pending, successful and failed output.
The example waits before resolving the profile so fallback remains visible. Its two actions start a successful run or a rejected run with a fresh suspenseKey.
Table of contents
Main APIs
- Suspense
- Renders fallback while asynchronous children resolve, then renders the result or error output.
tsximport { mount } from "valyrian.js";
import { Suspense } from "valyrian.js/suspense";
type Outcome = "success" | "error";
const state = { outcome: "success" as Outcome, run: 0 };
const wait = (milliseconds: number) =>
new Promise((resolve) => setTimeout(resolve, milliseconds));
async function Profile({ outcome }: { outcome: Outcome }) {
await wait(700);
if (outcome === "error") {
throw new Error("Profile request failed");
}
return <p>Loaded profile</p>;
}
function load(outcome: Outcome) {
state.outcome = outcome;
state.run += 1;
}
const Screen = () => {
const suspenseKey = `profile:${state.outcome}:${state.run}`;
return (
<main>
<button onclick={() => load("success")}>Load profile</button>
<button onclick={() => load("error")}>Load rejected profile</button>
<Suspense
suspenseKey={suspenseKey}
fallback={<p>Loading profile...</p>}
error={(error) => <p>{String(error)}</p>}
>
<Profile outcome={state.outcome} />
</Suspense>
</main>
);
};
mount("body", Screen);Error
The `error` renderer produces the failure output when an asynchronous child rejects.