How to Create a Blazor Component
Blazor components are a great way to write reusable code and follow the DRY principle. There are a few guidelines that are worth following when creating them and a couple ways to create them as well. We're going to start with the default project and turn the button on the Counter page into a component.
Create the project
In your terminal use this command to create a new Blazor WebAssembly project named BlazorApp: ~$ dotnet new blazorwasm -o BlazorApp
Navigate into the project and open it in your IDE of choice: ~$ cd BlazorApp
Create the component
I find it to be easier to keep things organized if we create a folder for our components. Let's create a folder named 'Components' and create our new component file named 'Button' in there.
The name of the file will be the case-sensitive name of the component. It's important to give your components unique names and the common convention in Blazor is to use Pascal Casing.
Another quick thing we're going to do before we continue is add the Components folder to _Imports.razor
so it's easily accessible everywhere:
@using BlazorApp.Components
This eliminates the need for you to have a using statement in every file that uses anything in the Components folder.
Let's add a button and some code to Button.razor:
<button class="btn btn-primary" @onclick="OnClick">
@Text
</button>
@code {
[Parameter]
public string Text { get; set; } = "Click me";
[Parameter]
public EventCallback OnClick { get; set; }
}
This is a pretty simple component. We have two parameters:
Text is a string with a default value of "Click me".
OnClick is how we add a handler to the click event
Use the component
Now we can replace the button in Counter.razor with our new Button component and see it in action!
<Button Text="My Button Text" OnClick="IncrementCount" />
That's it! Run the app, go to the Counter page and click away to watch the count go up.
Let's try something a bit more complicated.
Data Binding
Let's make a text input component that we can bind to. Data binding allows us to write code that will automatically update properties or allow us to handle when a value has changed. Let's create a new file for the new component TextInput.razor:
And add some code:
<input type="text" value="@Text"
@oninput="e => TextChanged.InvokeAsync(e.Value?.ToString())" />
@code {
[Parameter]
public string Text { get; set; } = string.Empty;
[Parameter]
public EventCallback<string> TextChanged { get; set; }
}
This new TextInput component allows us to bind to the Text property through a convention. You'll notice the TextChanged
property above. It has the same name as the property we are binding to with Changed
appended to it and the type in the angle brackets of EventCallback
matches the type of the property. Then all we need to do is InvokeAsync()
and the property is set up for binding!
Let's add this component to the Index page:
<TextInput @bind-Text="Text" />
<div>Your text: @Text</div>
@code {
private string Text { get; set; } = string.Empty;
}
Now we have a text input on the Index page and when we type in it the page updates to show the text just below it:
Required Parameters
If you design a component that requires a parameter for it to render properly there is a way to make it show a warning in your IDE when it hasn't been passed in. It's as simple as adding EditorRequired
to the Parameter
attribute:
// Button.razor
<button class="btn btn-primary" @onclick="OnClick">
@Text
</button>
@code {
[Parameter, EditorRequired]
public string Text { get; set; } = "Click me";
[Parameter]
public EventCallback OnClick { get; set; }
}
Now when you add a Button
to a page it will have a yellow squiggle underneath it in your IDE if the Text parameter has not been set!
I hope you found this helpful! Happy coding!