Previously, in Part 2, we toured
every file in ClinicApp and learned the series motto: everything is a
component.
Today we stop touring and start building. A component is a self-contained piece of UI — some markup, optionally some C# — that you define once and reuse anywhere. Think LEGO bricks: you don't sculpt a castle out of one lump of plastic; you snap together small bricks, and the same brick shows up in the wall, the tower, and the gate. In fact, the very site you're reading is built from Blazor components — the callout boxes, the code blocks, even the post wrapper around this article are bricks being reused over and over.
Build your first component: PatientCard
ClinicApp is a patient app, so let's make a brick that displays one patient.
In the Components folder, create a new file called
PatientCard.razor with this inside:
<div class="patient-card">
<h3>@Name</h3>
<p>Age: @Age</p>
</div>
@code {
[Parameter]
public string Name { get; set; } = "";
[Parameter]
public int Age { get; set; }
}
Recognize the zones from Part 2? Markup on top, a @code block below. The
markup is a simple div showing a name and an age, and the @Name
and @Age spots pull their values from the two properties in the code block.
That's the entire file — no ceremony, no registration step. The file is the
component, and its name is the tag you'll use: <PatientCard />.
Snap it into Home.razor
Now open Components/Pages/Home.razor and add three cards anywhere in the
markup:
<PatientCard Name="Asha" Age="34" />
<PatientCard Name="Ravi" Age="62" />
<PatientCard Name="Meera" Age="8" />
Run the app (you're using dotnet watch, right?) and there they are: three
patient cards, each with its own name and age, all rendered by the one file you just wrote.
Want ten patients? Ten tags. Want to change how every card looks? Edit one file. That's the
brick paying for itself already.
Tip: No using needed — remember _Imports.razor
from Part 2? It shares the project's namespaces with every component, which is why
Home.razor finds PatientCard automatically. Just make sure
your component names start with a capital letter, so Blazor can tell them apart from
plain HTML tags.
What's the deal with [Parameter]?
Why did we decorate Name and Age with [Parameter]?
Because components are deliberately private by default. A parent can only pass a value into
a property that is marked as a parameter — and it must be public, too.
Skip the attribute and Blazor won't accept Name="Asha"; it will stop you with
an error instead. Think of [Parameter] as the label on a brick's studs: it
marks exactly where other bricks are allowed to connect. Everything without the label stays
internal wiring.
The component tree
Here's the picture that ties this to Part 2. Components nest inside components, forming a component tree:
Read it from the top: App is the outer shell around everything. Inside it, the
layout draws the frame — sidebar, header — around whichever page the router picked. Inside
the layout sits the page, Home. And inside the page, our three
PatientCard bricks, each holding its own little patch of the screen. Every
Blazor app you'll ever build is exactly this shape: one tree, components all the way down,
with data flowing downward through parameters.
Note: There's a nice full-circle moment here. In
Conversation to System
Design, we modeled patients as data — an entity with attributes like name
and age. Now those same patients are becoming UI. Soon we'll connect the two
with a proper Patient model, and the design work and the app will meet in
the middle.
A peek ahead: components with slots
One teaser before we go. Parameters like Name pass in values — but
components can also accept whole chunks of markup, through a special parameter
called ChildContent. That's how you build things like a generic card, dialog,
or tab that wraps whatever content you place between its opening and closing tags — it's
how this site's callout boxes work. It's an intermediate move, so we'll park it for now and
come back once the fundamentals are solid.
What's next
Our cards look nice, but they just sit there — you can't click them, edit them, or make them react. In Part 4, we bring the app to life with data binding and event handling: buttons that do things, inputs that update the page as you type. That's where Blazor starts feeling alive. See you there!