Understanding Blazor Components
This Dev Note is a practical walkthrough of several core Blazor concepts: components, state, rendering, parameters, and communication between parent and child components.
Rather than trying to explain all of Blazor at once, this note focuses on the main patterns that make Blazor applications work. The goal is to make the framework easier to reason about, not just easier to copy from examples.
Main Focus
Components, state, rendering, communication
Framework
Blazor / Razor Components
Use Case
Learning the mental model behind Blazor UI development
What Makes Blazor Different?
Blazor lets developers build interactive web interfaces using C# and Razor
components instead of relying entirely on JavaScript for client-side behavior.
A Blazor component combines markup and logic in a single .razor file.
This means UI behavior can often be written using the same language and tooling used elsewhere in a .NET application.
A Simple Blazor Component
Here is a small component that displays a message and updates it when a button is clicked:
<h3>Hello Blazor</h3>
<p>@message</p>
<button @onclick="ChangeMessage">Click me</button>
@code {
string message = "The component is alive.";
void ChangeMessage()
{
message = "The message changed!";
}
}
This example demonstrates several important ideas at once:
- Markup and C# logic live in the same component
@messageinserts C# state into the rendered output@onclickbinds a UI event to a C# method- Changing component state causes the UI to update
State and Re-Rendering
A core concept in Blazor is that components render based on their current state. When the state changes, Blazor re-renders the component and updates the UI.
In the previous example, the value of message changes when the button
is clicked. Blazor detects the change and updates the output shown in the browser.
Lifecycle Basics
Blazor components have lifecycle methods that run at different moments during initialization and rendering.
A common early example is OnInitialized():
@code {
string message = "";
protected override void OnInitialized()
{
message = "Component initialized.";
}
}
Some useful lifecycle methods to know early on are:
OnInitialized— runs when the component is initializedOnParametersSet— runs when parameters are received or updatedOnAfterRender— runs after rendering has completed
You do not need to memorize them all immediately, but it helps to know that Blazor components follow a defined lifecycle rather than rendering magically out of nowhere.
Parameters: Passing Data to a Child Component
A Blazor component can accept values from a parent using parameters. This is one of the main ways components become reusable.
Example child component:
<h4>Hello @Name</h4>
@code {
[Parameter]
public string Name { get; set; }
}
Example parent usage:
<ChildComponent Name="Joel" />
Here the parent passes a value into the child component. The child receives it
through a property marked with [Parameter].
Sending Information Back Up with EventCallback
Passing data down is only part of component communication. Sometimes a child component needs to notify its parent that something happened.
Example child component:
<button @onclick="SendMessage">Notify Parent</button>
@code {
[Parameter]
public EventCallback<string> OnMessage { get; set; }
async Task SendMessage()
{
await OnMessage.InvokeAsync("Child says hello.");
}
}
Example parent usage:
<ChildComponent OnMessage="HandleMessage" />
@code {
string childMessage = "";
void HandleMessage(string message)
{
childMessage = message;
}
}
This pattern allows a child component to trigger behavior in its parent without tightly coupling the two components together.
Blazor Server vs Blazor WebAssembly
Blazor has more than one hosting model, and understanding the distinction helps explain why different Blazor apps behave differently.
Blazor Server
- Components execute on the server
- The browser communicates with the server over SignalR
- UI updates are sent back to the client
Blazor WebAssembly
- The .NET runtime runs in the browser via WebAssembly
- Components execute on the client
- The app can behave more like a client-side SPA
A Tiny Mental Model
A concise way to think about many Blazor interactions is:
state → render → event → state
That loop appears again and again:
- state is displayed in the UI
- the UI renders based on that state
- the user triggers an event
- the event changes state
- Blazor re-renders the component
A Simple Counter Example
This small example shows the state/render/event loop in one place:
<p>Count: @count</p>
<button @onclick="Increment">Increment</button>
@code {
int count = 0;
void Increment()
{
count++;
}
}
Even though this example is tiny, the same pattern scales up into more complex interactive components and applications.
Why These Concepts Matter
It is easy to build Blazor pages by copying examples without forming a strong mental model. Understanding components, state, parameters, and callbacks makes the framework more predictable and easier to debug.
Once these ideas feel natural, larger topics such as forms, dependency injection, routing, and shared state become much easier to approach.
