You can find a summary of the code updates in this pull request . Read on for explanations.
1. Create new state
Let’s start by creating the status
state with a value that’s one of three possible strings: “idle”, “loading”, and “error”.
For TypeScript, we’ll define the Status
type as a union of three string literals .
page.tsx
type Status = "idle" | "loading" | "error";
export default function Home() {
const [quote, setQuote] = React.useState<string>();
const [status, setStatus] = React.useState<Status>("idle");
// ...
}
The initial value is “idle”, since there are no pending requests (or errors) when the component mounts.
2. Update state in handleClick
Then we can manage the status
value in handleClick
. We’ll set the state to “loading” at the start of the function, and then set it back to “idle” once all of the async functions have returned.
page.tsx
const handleClick = async () => {
// start request
setStatus("loading");
const response = await fetch("/api/get-quote-styles");
const json = await response.json();
setQuote(json.quote);
// set status back to idle
// after everything's settled
setStatus("idle");
};
3. Watch state in console
Eventually, we will update the UI depending on the status
value. For now, though, we’ll watch the value via console.log
. The component will re-render every time there’s a state update. So if we put a console.log
statement in the component function body, we’ll get an updated value logged on every re-render.
page.tsx
export default function Home() {
const [quote, setQuote] = React.useState<string>();
const [status, setStatus] = React.useState<Status>("idle");
console.log('STATUS', status)
//...
}
You’ll see something like this after you click the button (make sure your server is running first!):

Up next
In the next workshop, we’ll handle errors that occur while fetching data.