blazor with ComponentBus

Use ComponentBus to Managing Dynamic Components in Blazor Efficiently

Is It Vritra - SDE I

--

As a developer, you often encounter scenarios where you need to manage dynamic UI elements efficiently. For instance, in a social media application, you might want to avoid including a comment popup modal in every post when infinite posts are loading on a single page. How can you handle such scenarios effectively in Blazor?

One powerful solution is using a pub-sub model to manage component communication. This article explores how to achieve this using the ComponentBus library.

Modern Problem: Dynamic UI Elements at Scale

Imagine you’re building a social media platform with Blazor. Your application features an infinite-scrolling feed of posts, each with its comment section that opens in a modal. The naive approach would be to include a comment modal component within each post component. However, this leads to several issues:

  1. As the number of posts increases, so does the number of modal instances, potentially impacting the application’s performance. [Performance Degradation]
  2. Each modal instance consumes memory, even when not in use [Memory Overhead]
  3. Keeping track of which modal should be open and managing its state becomes increasingly difficult. [Complex State Management]

These challenges call for a more sophisticated solution that can handle dynamic UI elements efficiently, even as the application scales.

modern problem modern meme

Modern Solution: ComponentBus [pub-sub]

ComponentBus introduces a publish-subscribe (pub-sub) communication model to Blazor applications. This pattern allows components to communicate without direct references, providing a flexible and scalable approach to managing dynamic UI elements.

scroll to the end for pros and cons… 🔻

Let’s walk through the process of integrating ComponentBus into a Blazor application, using our social media platform example

Step 1: Setting Up ComponentBus

First, install the ComponentBus NuGet package:

dotnet add package ComponentBus

Then, register the ComponentBus service in your Program.cs or Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
services.AddRazorComponents();
services.AddSingleton<IComponentBus, ComponentBus>();
}

Step 2: Defining Message Types

Create message classes to encapsulate the information needed for different operations. For our comment modal example:

public class OpenCommentModalMessage
{
public int PostId { get; set; }
public string PostTitle { get; set; }
}

public class CloseCommentModalMessage { }

Step 3: Publishing Messages

In your post component, publish an OpenCommentModalMessage when the comment button is clicked:

@inject IComponentBus ComponentBus

<div class="post">
<h2>@Title</h2>
<p>@Content</p>
<button @onclick="OpenComments">View Comments</button>
</div>

@code {
[Parameter] public int Id { get; set; }
[Parameter] public string Title { get; set; }
[Parameter] public string Content { get; set; }

private void OpenComments()
{
ComponentBus.Publish(new OpenCommentModalMessage
{
PostId = Id,
PostTitle = Title
});
}
}

Step 4: Subscribing to Messages

Create a single CommentModal component that subscribes to the OpenCommentModalMessage:

@inject IComponentBus ComponentBus

@if (isVisible)
{
<div class="modal">
<h3>Comments for: @currentPostTitle</h3>
<!-- Comment list and form go here -->
<button @onclick="CloseModal">Close</button>
</div>
}

@code {
private bool isVisible = false;
private int currentPostId;
private string currentPostTitle;

protected override void OnInitialized()
{
ComponentBus.Subscribe<OpenCommentModalMessage>(HandleOpenModal);
ComponentBus.Subscribe<CloseCommentModalMessage>(_ => CloseModal());
}

private void HandleOpenModal(OpenCommentModalMessage message)
{
currentPostId = message.PostId;
currentPostTitle = message.PostTitle;
isVisible = true;
StateHasChanged();
}

private void CloseModal()
{
isVisible = false;
StateHasChanged();
}
}

Step 5: Integrating the Modal

Add the CommentModal component once in your main layout or page:

@page "/"

<h1>Social Media Feed</h1>
<PostList />
<CommentModal />

That’s it!! Done

wait there is more…

Advanced Techniques and Best Practices

1. Message Filtering

ComponentBus allows you to filter messages based on certain criteria. This is useful when you want to handle messages differently based on their content:

ComponentBus.Subscribe<OpenCommentModalMessage>(
message => message.PostId > 1000,
HandleRecentPostComments);

2. Unsubscribing

Always unsubscribe from messages when a component is disposed to prevent memory leaks:

private IDisposable subscription;

protected override void OnInitialized()
{
subscription = ComponentBus.Subscribe<OpenCommentModalMessage>(HandleOpenModal);
}

public void Dispose()
{
subscription.Dispose();
}

3. Typed Messages

Use interfaces to create a hierarchy of message types for more flexible handling:

public interface IModalMessage
{
string ModalType { get; }
}

public class OpenCommentModalMessage : IModalMessage
{
public string ModalType => "Comment";
public int PostId { get; set; }
}

public class OpenShareModalMessage : IModalMessage
{
public string ModalType => "Share";
public int PostId { get; set; }
}

// In your modal component
ComponentBus.Subscribe<IModalMessage>(HandleModalMessage);

for explaination, comment “exp typed messages”

4. Performance Considerations

While ComponentBus is generally efficient, be mindful of publishing high-frequency messages or having too many subscribers, as this can impact performance. Use profiling tools to monitor your application’s performance and optimize as needed.

let’s compare it to other common approaches in Blazor:

1. Cascading Parameters:

Pros: Built into Blazor, good for passing data down the component tree.

Cons: Can be cumbersome for deep component hierarchies, not suitable for event-driven scenarios.

2. State Containers (e.g., Fluxor):

Pros: Centralized state management, good for complex applications.

Cons: Steeper learning curve, can be overkill for simpler scenarios.

3. SignalR:

Pros: Real-time communication, good for multi-user scenarios.

Cons: Requires server setup, more complex to implement for client-side-only communication.

4. ComponentBus:

Pros: Decoupled communication, easy to implement, flexible for various scenarios.

Cons: It requires careful management of subscriptions, and there is the potential for overuse in simple applications.

Conclusion

ComponentBus offers a powerful and flexible solution for managing dynamic UI elements in Blazor applications. By leveraging the pub-sub model, developers can create more scalable, maintainable, and performant applications. Whether you’re building a complex social media platform or any application with dynamic components, ComponentBus provides the tools to streamline your development process and create more robust Blazor applications.

As you integrate ComponentBus into your projects, remember to follow best practices, consider performance implications, and always profile your application to ensure optimal performance. With these considerations in mind, ComponentBus can significantly enhance your Blazor development experience, allowing you to focus on creating exceptional user experiences without getting bogged down in complex component communication challenges.

🟢 Pros

Decoupled Architecture: Components can interact without being directly aware of each other, promoting a more modular design.

Improved Performance: By centralizing dynamic elements like modals, you can significantly reduce the number of component instances.

Simplified State Management: The pub-sub model facilitates easier state management across components.

Enhanced Scalability: As your application grows, ComponentBus scales effortlessly, maintaining performance and maintainability.

--

--

Is It Vritra - SDE I
Is It Vritra - SDE I

Written by Is It Vritra - SDE I

Going on tech shits! AI is my pronouns

No responses yet