11
- June
2020
Posted By : Rahul
Deep dive on Blazor Components – ASP.NET Core

I hope many of you already heard this word Components with modern front-end JavaScript frameworks like Angular & React. but here we are going to discuss about the Blazor components. Did you ever hear about components in Blazor?

No?? No problem! I am here 😊 to help you to understand what are components in ASP.NET Core Blazor? not in Angular or another framework in this article.

In our previous article, we discussed about Blazor, about WebAssembly and creating a Blazor server app and Blazor client app in Getting Started with ASP.NET Core Blazor. In this article, we will go a bit deeper into Blazor components.

What is Component in Blazor?

Blazor is a component driven framework. It means that components are basic building blocks of a Blazor application. In simple words, A component in Blazor is a combination of -:

  • HTML
  • Razor
  • C# Code

Components can be reused, nested and shared between multiple projects using Razor library project. Extension of a component file in a Blazor application is .razor.

👉 Remember, Component file name must start with an uppercase character, otherwise Blazor framework will give you compile-time error.

Ex. counter.razor : Not allowed, Counter.razor : Allowed

Now let’s take a look at default generated component with Blazor server or Blazor WebAssembly project. If you are not aware with these two types, please visit my last article.

first-blazor-component

As shown in above image, we have a Counter.razor component that has two blocks. One is HTML block (with Razor) and other one is C# code block. However there are few other approaches for creating components where these two blocks will be in two different files instead of one file. We will talk about these methods later in this same article. For this time let’s proceed with this inline (single) file approach.

Out of the box components come with Blazor Framework

There are couple of out of the box components that are used in a blazor app. You can see all of them in App.razor file in the root of your Blazor application.

<!-- App.razor -->
<Router AppAssembly="@typeof(Program).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
    </Found>
    <NotFound>
        <LayoutView Layout="@typeof(MainLayout)">
            <p>Sorry, there's nothing at this address.</p>
        </LayoutView>
    </NotFound>
</Router>

👉 Router Component – The Router component enables routing to each component with a specified route.
👉 RouteView Component – The RouteView component receives the route data and the default layout.
👉 LayoutView Component – The LayoutView component takes layout and displays the specified content inside the specified layout and any further nested layouts.
👉 Found & NotFound Components – Blazor routing mechanism renders the Found component if any component route matched else renders the NotFound component.

We will discuss all of them in detail in our upcoming articles about Blazor Routing & Blazor Layouts.

How components compiles and renders in Blazor?

One thing to keep in mind that when this component will be compiled with build process, this HTML with Razor block and C# code block (means Counter.razor file) would be end up as a class file called Counter.razor.g.cs with a partial C# class with same name as file name Counter inherited from Microsoft.AspNetCore.Components.ComponentBase.  If you want to see the code of this class, you can go to the location “\obj\Debug\netstandard2.1\Razor\Pages” and view the code of the file.

blazor-component-compilation

After running the application, the component is initially rendered and displayed in the browser. When any event triggers, it regenerate its render tree, then Blazor compares the new render tree against the previous one and applies any differences to the browser’s DOM.

Nested Blazor Components

A component in Blazor app can be nested inside other components. As of now we saw only counter component. There are few other components that generate with default template inside Pages folder (as shown in above image). Let’s take a look how can we nested Counter component (Counter.razor) inside Index component (Index.razor).

nested-blazor-components

As Index is root component that means when application will load, initially Index component will be rendered and we nested Counter component two times inside Index component (as shown in above image), this will be rendered twice.

Now run the app and see the following output.

nested-blazor-components-output

What is Page in Blazor?

A page is nothing but a component with @page directive that tells Blazor how you can access this page/component directly in the browser, especially when you are not nesting it inside any parent page/component.

Did you notice @page directive inside index component (/Pages/Index.razor) previously? No, don’t worry 😊. We’ll discuss about it right away.

About @page directive

@page is a directive that specifies the URL for the component through which you can access this page (component) in the browser. Remember, earlier we discussed above about Blazor component compile process. In short, when a Blazor component (.razor file) with @page directive is compiled, @page directive is converted to RouteAttribute in the generated class. Let’s take a look at compiled component file again. We will discuss more in detail about Blazor Routing in our upcoming articles.

how-page-directive-compile-blazor

Hope 😊 you have a good understanding now about Blazor page & Blazor component both.

In a nutshell, A component with @page directive is called page in Blazor app that can be accessed directly in the browser using route URL specified inside @page directive. A page (component) can be nested inside other pages (components). When you embed a page inside another page, Blazor treats it as a component.

Creating a component

There are four approaches for creating a component. Let see all of them in detail.

Method#1 – Inline approach

This is very simple way to create a blazor component. Using this approach, HTML as well as C# code both are in a single file. Remember, we discussed about Counter component in above example, where we saw HTML & C# code were inside a single file called Counter.razor.

<!-- Counter.razor -->	
<p>First Name: @name</p>
	
@code {
     public string name = "Rahul";
}

Method#2 –Partial Class approach

Using this approach, HTML (with Razor syntax) and C# code are separated into two different files. Let’s create a new component named “ProductList” inside the Pages folder.

  • Right click on Pages -> Add -> New Item
create-blazor-component
  • In Add New Item window, search for Blazor in search box and then select the Blazor Component form the list. Change name of default component as “ProductList.razor” and click on Add button.
create-blazor-component-step2
  • By default, Blazor generated component supporting inline approach. So remove @code block from “ProductList.razor” file and add a new class file with the same name of razor file called “ProductList.cs”.

    Since we have to use partial approach, Add partial keyword to the ProductList class. Now add a Title property in ProductList class and use it inside ProductList.razor file just to display data bind to this title property on ProductList component.
create-blazor-component-using-partial-approach
  • Now nest this ProductList component inside Index component (page).
nest-compnent

👉 Remember, When you nest your component inside other component, nested component would be in purple colour automatically. If not in your case, it means that Blazor is unable to find your component. It may be due to namespace. It means that your component may not be created inside the same folder where your parent component exists.

For example, if you create a new folder called “Custom” (any name you want) and create a new component inside this folder. And now if you want to nest this new component inside Index component (page), then there are two ways to get access of it –

👉🏻 Use fully qualified name of component

<!--  Index.razor -->

<FirstBlazorWASMApp.Custom.ProductList>/FirstBlazorWASMApp.Custom.ProductList>

👉🏻 Register your component namespace using @using directive inside “_Imports.razor” file

<!--  _Imports.razor -->
			
@using FirstBlazorClientApp.Custom

and use your component name only to nest it inside Index component

<!--  Index.razor -->
			
<ProductList></ProductList>

Method#3 –Base Class approach

This is similar to Partial Class approach in which HTML (with Razor syntax) and C# code are separated into two different files. But there are two things we need to care about –

  • First, we need to inherit our class from ComponentBase that comes from “Microsoft.AspNetCore.Components” namespace.
  • Second, we need to use @inherits directive with name of class name inside blazor file.

Let’s create a new component called “DisplayComponent”. For creating this component, we will have to do the same as we did in partial class approach (above). Add a new razor component “DisplayProduct.razor” and add a class file “DisplayProductComponent.cs”.

create-component-using-base-class-approach

Make sure, Class name must be different from Razor file name ( which is DisplayProductComponent in my case). Otherwise Blazor will give you compile-time error.

Method#4 –Class Only approach

This is final approach for building components in Blazor. In this approach, only single class file is needed for single component. No razor file is required.

As you already know whatever approach (out of all three discussed earlier) you will use to create component, ultimately all components would be compiled to a class file only.

Let’s create a component using class only approach. Add a new class “ClassOnlyApproachComponent.cs” and add following code –

<!--  ClassOnlyApproachComponent.razor -->
	
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Rendering;
	
namespace FirstBlazorClientApp.Pages
{
    public class ClassOnlyApproachComponent: ComponentBase
    {
	  public string Title = "This component is rendered using class-only approach.";
	
	protected override void BuildRenderTree(RenderTreeBuilder builder)
	{
	   builder.OpenElement(1, "h3");
	   builder.AddContent(2, Title);
	   builder.CloseElement();
	}
    }
}

In this approach, class is inherited from ComponentBase and a method BuildRenderTree is overridden for getting access the RenderTreeBuilder instance, which is basically used to create our component view programmatically. At the runtime, component will be following output –

render-component-usig-classonly-approach

All Components nested inside Index page (component)

Let see output of all created components as nested inside index page –

all-components-output

Summary

In this article, we have covered –

👉 What is Page or Component in Blazor app?
👉 What are Router, RouteView, LayoutView, Found & NotFound components that come out of the box with Blazor app?
👉 How Blazor component compiled and rendered?
👉 How many ways for creating a Blazor component?
👉 How components are nested inside other components?

In our next article, we will cover about component lifecycle methods and data binding in Blazor in detail.

Thank you 🙏 for reading this article. Keep Reading, Keep Growing, Keep Sharing 😃


If you found this article helpful,

BMC logoBuy me a coffee


Follow Us For Latest Posts –

Leave a Reply