Declaring parameters on a component
In Blazor, component parameters allow you to pass data into components. It’s the first step in making your application dynamic. Component parameters are like method parameters in traditional programming. You can utilize the same primitive, as well as the reference and complex types. This results in code flexibility, simplified UI structures, and high markup reusability.
Let’s create a parametrized component that represents a ticket so that we can display any incoming tariff and price without unnecessary code duplication or markup incoherence.
Getting ready
Before you dive into component parameterization, do the following:
- Create a
Recipe03
directory – this will be your working directory - Copy the
Ticket
component from the Creating your first basic component recipe or copy its implementation from theChapter01
/Recipe02
directory of this book’s GitHub repository
How to do it...
To declare parameters on your component, start with these foundational steps:
- In the
Ticket
component, declare parameters in the@
code
block:@code { [Parameter] public string Tariff { get; set; } [Parameter] public decimal Price { get; set; } [Parameter] public EventCallback OnAdded { get; set; } }
- Modify the
Ticket
markup so that you can render values from parameters:<div class="ticket"> <div class="name">@Tariff</div> <div class="price"> @(Price.ToString("0.00 $")) </div> <div class="ticket-actions"> <button @onclick="@OnAdded"> Add to cart </button> </div> </div>
- Create an
Offer
page and enhance it so that it renders inInteractiveWebAssembly
mode:@page "/ch01r03" @rendermode InteractiveWebAssembly
- Below the functional directives in the
Offer
component, add two parametrized instances ofTicket
. Implement anAdd()
method as a placeholder for interactivity:<Ticket Tariff="Adult" Price="10.00m" OnAdded="@Add" /> <Ticket Tariff="Child" Price="5.00m" OnAdded="@Add" /> @code { private void Add() => Console.WriteLine("Added to cart!"); }
How it works...
In step 1, we extended the Ticket
component with a @code
block, which Blazor recognizes as a container for the C# code. Within this @code
block, we used the Parameter
attribute to mark properties that are settable externally, such as method arguments in C#. In our example, we used a string for a ticket tariff and a decimal for its price. For the last parameter, we used the EventCallback
type. It’s a Blazor-specific struct
that carries an invokable action with an additional benefit. When you change the UI state, you should use the StateHasChanged()
life cycle method to notify Blazor that something happened. By design, EventCallback
triggers StateHasChanged()
automatically, so you can’t omit it accidentally. In step 2, we rebuilt the Ticket
markup based on parameter values that we accessed using the @
symbol. That symbol signaled to the compiler that we were switching to dynamic C# code. If you pair it with round brackets, you can embed complex code blocks as well, as we did when we formatted the price in a money format.
In step 3, we created a navigable Offer
page. This time, on top of the @page
directive, we also declared a @rendermode
directive, which allowed us to control how our component renders initially. We can choose from any of the render modes that a Blazor Web App supports, but as we expect some interactivity on the page, we opted for InteractiveWebAssembly
mode. In step 4, in the @code
block of Offer
, we implemented an Add()
placeholder method that simulates adding a ticket to the cart. We also implemented the Offer
markup, where we rendered two Ticket
instances with different parameters. You pass parameter values similarly to standard HTML attributes such as class
or style
. Blazor automatically recognizes that you’re calling a component, not an HTML element. Finally, we rendered Adult and Child tickets and attached the Add()
method to the exposed EventCallback
parameter.
There’s more...
You must be aware that the number of parameters can directly affect the rendering speed. That’s because the renderer uses reflection to resolve parameter values. Over-reliance on reflection can significantly hinder performance. You can optimize that process by overriding the SetParametersAsync()
method of the component life cycle, though that’s an advanced operation. Instead, you should focus on keeping the parameters list concise or introducing wrapper classes where necessary.
Earlier in this chapter, we declared a specific render mode for a component when your Blazor application is set to expect interactivity at the page or component level. However, when you enable interactivity globally, you can still exclude certain pages from interactive routing. You’ll find it useful for pages that depend on standard request/response cycles or reading or writing HTTP cookies:
@attribute [ExcludeFromInteractiveRouting]
To enforce static server-side rendering on a page, you must add the ExcludeFromInteractiveRouting
attribute, using the @attribute
directive, at the top of the page. In this case, you no longer add the @rendermode
directive as it’s dedicated to declaring interactive render modes.