Load components dynamically in Blazor
Blazor apps consist of one or more Razor components that reside in .razor
files. Usually, you place a component in a page at development time. However, at
times you may want to load components on the fly based on some logic. That means
you don't know the component to be loaded at the development time. That will be
known only during run-time. Luckily, Blazor provides what is known as
Dynamic Component that can be used to deal with such situation. In this
article you will learn how Dynamic Component can be used in a Blazor Server app.
Begin by creating a new Blazor Server app called DynamicComponentDemo. Make
sure to pick .NET 6.0 as the target framework while creating the project.
The newly created app with a bunch of default files is shown below.
Now add a new Razor component in the Pages folder named MainComponent.razor
Add four more Razor componenmts namely Hello.razor, HelloWorld.razor,
HelloGalaxy.razor, and HelloUniverse.razor. Your Solution Explorer will look
like this after adding all the components.
Then open Hello.razor and add the following markup to it.
<h3>Hello from Blazor !!!</h3>
Repeat the process with HelloWorld.razor, HelloGalaxy.razor, and
HelloUniverse.razor, and add respective messages.
<h3>Hello World from Blazor !!!</h3> <!-- HelloWorld.razor -->
<h3>Hello Galaxy from Blazor !!!</h3> <!-- HelloGalaxy.razor -->
<h3>Hello Universe from Blazor !!!</h3> <!-- HelloUniverse.razor -->
We will now load these components dynamically in the MainComponent using
Blazor's Dynamic Component.
So, open MainComponent.razor and add the following markup:
@page "/maincomponent"
<button @onclick="OnHelloWorldClick">Hello World!</button>
<button @onclick="OnHelloGalaxyClick">Hello Galaxy!</button>
<button @onclick="OnHelloUniverseClick">Hello Universe!</button>
<br /><br />
<DynamicComponent Type="@dyncompType" />
As you can see, we have set the page route to /maincomponent. The component
has three <button> elements. The onclick event handler is wired to
OnHelloWorldClick, OnHelloGalaxyClick, and OnHelloUniverseClick event handler
functions respectively.
Then there is <DynamicComponent> component and its Type property is set to
dyncompType. The dyncompType variable is in the @code block and you will add it
shortly. The Type property points to the System.Type of a component that
will be loaded by the Dynamic Component.
Next, add a @code block and write the event handlers mentioned above.
@code {
Type dyncompType = typeof(Hello);
public void OnHelloWorldClick()
{
dyncompType = typeof(HelloWorld);
}
public void OnHelloGalaxyClick()
{
dyncompType = typeof(HelloGalaxy);
}
public void OnHelloUniverseClick()
{
dyncompType = typeof(HelloUniverse);
}
}
The @code block declares a Type variable called dyncompType. The
DynamicComponent's Type property can't be a null value. So, we initialize the
dyncompType variable with the Type of Hello component.
The three event handler functions simply set the dyncompType variable to the
respective component's Type.
If you run the application and navigae to /maincomponent, you should see
this:
As you can see, the default Hello.razor component is loaded by the
DynamicComponent.
Clicking on the three buttons will load the respective components. For
example, clicking on the Hello Universe! button will load
HelloUniverse.razor component as shown below:
Blazor components often accept parameters. Even a dynamically loaded
component might want to have parameters passed to it from the MainComponent. You
can do that using the Parameters property of DynamicComponent. The Parameters
property is a Dictionary of parameters and their values.
Let's modify our components to accept a Value parameter.
Open Hello.razor and modify it as shown below:
<h3>Hello from Blazor !!!</h3>
<h4>Value : @Value</h4>
@code {
[Parameter]
public string Value { get; set; }
}
As you can see, the component now has Value property decorated with
[Parameter] attribute. The Value is outputted in a <h4> element.
Repeat this process for HelloWorld.razor, HelloGalaxy.razor, and
HelloUniverse.razor compoenents.
Now open MainComponent.razor and modify the <DynamicComponent> like this:
<DynamicComponent Type="@dyncompType"
Parameters="@dyncompParams" />
We set Parameters property to dyncompParams dictionary. The dyncompParams
dictionary is populated in the @code block as shown below.
@code {
Type dyncompType = typeof(Hello);
Dictionary<string, object> dyncompParams =
new Dictionary<string, object>()
{
{"Value","This is a default value" }
};
...
...
}
As you can see, we created a Dictionary<string, object> named dyncompParams.
Initially, a default Value is added to the Dictionary so that Hello.razor gets
this default value. Values for the other three components are set in the
respective event handlers. As an example OnHelloGalaxyClick() event handler is
shown below:
public void OnHelloGalaxyClick()
{
dyncompParams = new Dictionary<string, object>()
{
{"Value","This is a value for Hello Galaxy component." }
};
dyncompType = typeof(HelloGalaxy);
}
Run the application again and click on the Hello Galaxy! button. You will see
the Value as shown below:
That's it for now! Keep coding!!