Communicating between Blazor components using StateContainer
This article explains about the communicating between Blazor components using state container.
State container
Blazor components can share access to data using in state container. State container class can use Action to notify components of the app state changes.
The below SessionGlobals class stores the value of the text to be displayed in the textbox and a method to update the value in the textbox. It also contains the OnChange event, which updated the value of the textbox to be displayed.
public class SessionGlobals { public String? MainMessage { get; set; } = "Initial Value."; public event Action OnChange; public void SetMessage(string message) { MainMessage = message; NotifyStateChanged(); } private void NotifyStateChanged() => OnChange?.Invoke(); }
Registering state container as service
Now, register this SessionGlobals state container as a Scoped service.
In Program.cs for .NET 6 Blazor Server and Blazor Web Assembly application.
// Add services to the container. . . . . builder.Services.AddSyncfusionBlazor(); builder.Services.AddScoped<SessionGlobals>(); var app = builder.Build();
In Startup.cs for .NET 5 and NET 3.X application.
public class Startup { public void ConfigureServices(IServiceCollection services) { . . . services.AddSyncfusionBlazor(); services.AddScoped<SessionGlobals>(); } }
Implement communication between Blazor components using state container
Now, add the two TextBox’s one in the application, one in MainLayout.razor page and other in the index.razor.
MainLayout.razor
@inherits LayoutComponentBase @inject SessionGlobals sessionGlobals; @implements IDisposable <div class="page"> <div class="sidebar"> <NavMenu /> </div> <main> <div class="top-row px-4"> <SfTextBox Value="@sessionGlobals.MainMessage" ></SfTextBox> <a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a> </div> .... </main> </div> @code { protected override void OnInitialized() { sessionGlobals.OnChange += StateHasChanged; } public void Dispose() { sessionGlobals.OnChange -= StateHasChanged; } }
Index.razor
@inject SessionGlobals sessionGlobals; <SfTextBox Value="@sessionGlobals.MainMessage" ></SfTextBox> <SfButton @ref="ToggleBtn" @onclick="onToggleClick" CssClass="e-flat" IsToggle="true" IsPrimary="true" Content="@Content"></SfButton> @code{ SfButton? ToggleBtn; public string Content = "Play"; private void onToggleClick(Microsoft.AspNetCore.Components.Web.MouseEventArgs args) { if (ToggleBtn?.Content == "Play") { this.Content = "Pause"; sessionGlobals.SetMessage("Now hit Pause"); } else { this.Content = "Play"; sessionGlobals.SetMessage("Now hit Play"); } } protected override void OnInitialized() { sessionGlobals.OnChange += StateHasChanged; } public void Dispose() { sessionGlobals.OnChange -= StateHasChanged; } }
Textbox component in both pages bind to property in state container. Also, run time changes update by listening to OnChange event of state container. Whenever the button is clicked state container property value is updated and OnChange call back invokes StateHasChanged which refresh the value in the TextBox.
See also
3 ways to communicate between components in blazor