You can find a summary of the code updates in this pull request . Read on for explanations.
1. Basic page layout
Let’s start with the basic page layout. There will be a Button
with text “use random quote”, a Separator
and a Card
. We’ll add these to the Home
component in src/app/page.tsx, which displays at the top level of the app.
Note, @
is the default alias for the src
directory. So "@/components/Button"
is equivalent to an absolute path of "src/components/Button"
(starting at the top level of the project). This keeps us from having to use relative imports (like "../components/Button"
). The relative path isn’t too bad here, since we only need to go up one level. But it can get messy if you have to go up half a dozen levels ("../../../../../../"
) before you get to the folder you need.
page.tsx
Card props
The above code will generate a TypeScript error for Card
that we’re missing some props:
The colors don’t really matter for now (in the next series, they’ll be selected by AI based on the quote content). I chose aliceBlue
and mediumBlue
from the named web colors ]:
If we start up the app with npm run dev
and visit http://localhost:3000 , it looks like this:
(The empty card on page load is not a great user experience; we’ll take care of that in the next workshop.)
2. Add onClick handler
All right, now let’s add an onClick handler for the Button
. We’ll create a function called (conventionally) handleClick
and then run fetch to access the endpoint. Since fetch
is an async function , we need to await
it and specify handleClick
as async
.
page.tsx
Get JSON
Great! Now we’ve contacted the server and stored the response in a variable. To get the JSON from the Response object , we need to run the (async) method .json()
page.tsx
Add state
Ok, so we’ve got the JSON. How do we display the quote in the UI? Because handleClick
is async, the only way to update the component after we get the response is to use state . Here’s what that looks like:
page.tsx
Now we have the json.quote
value from the response stored in the state variable quote
.
Display the quote
Since the quote
state contains the display value, we can plunk it into the Card
.
page.tsx
handleClick summary
Here’s the sequence of what will happen when the button is clicked:
quote
state starts out asundefined
(since we didn’t pass an argument touseState
), so theCard
is empty.handleClick
will run on button click.- After the
fetch
call is complete, theresponse
variable will contain theResponse
object returned fromfetch
. - After the
.json()
method has completed, thejson
variable will contain the JSON fromresponse
, and thequote
state will be set tojson.quote
. - Because state has been updated the component will re-render.
- On the next render,
quote
will have the value, and it will show in theCard
.
Up next
We’ll improve the user experience by adding a loading spinner while the fetch is in progress.
Workshops in this series
- Quotation endpoint
- Display fetched data
- Loading state
- Error state
- Custom hook
- Conditional rendering