In this lesson, you will learn how to create a centralized state container to synchronize UI data across your Blazor application.
Understanding the "Store" Pattern
In complex applications, passing data through parent-child component chains becomes messy, especially when multiple disconnected components need to react to the same information. A "Store" is simply a specialized service class that acts as a single source of truth for your UI state.
Instead of passing values down through parameters, you inject this service into any component that needs to read or modify that state.
Implementing a State Container
To implement this, create a service that holds your data and provides an event to notify subscribers when that data changes.
public class AppState
{
public string UserGreeting { get; private set; } = "Hello, Guest!";
// An event other components can subscribe to
public event Action? OnChange;
public void UpdateGreeting(string newName)
{
UserGreeting = $"Hello, {newName}!";
NotifyStateChanged();
}
private void NotifyStateChanged() => OnChange?.Invoke();
}
Using the Store in Components
Once registered in your Program.cs via Dependency Injection, you can use the store in your Razor components. Because Blazor components need to know when to re-render after the state changes, they subscribe to the OnChange event:
@inject AppState State
@implements IDisposable
<p>@State.UserGreeting</p>
<button @onclick="() => State.UpdateGreeting('Developer')">Update</button>
@code {
protected override void OnInitialized() => State.OnChange += StateHasChanged;
public void Dispose() => State.OnChange -= StateHasChanged;
}
The component calls StateHasChanged whenever the OnChange event fires, ensuring the UI stays in sync with the underlying data. By implementing IDisposable, we ensure the component unsubscribes from the event when destroyed, preventing memory leaks. This pattern turns a tangled web of event callbacks into a clean, predictable flow of data.
Key Takeaway: A UI Store uses a service to hold shared data and an Action event to notify components when they need to refresh, providing a robust way to manage global state without complex component drilling.