AspNetCore.Docs/aspnetcore/blazor/includes/state-container.md

2.8 KiB

no-loc
appsettings.json
ASP.NET Core Identity
cookie
Cookie
Blazor
Blazor Server
Blazor WebAssembly
Identity
Let's Encrypt
Razor
SignalR

Nested components typically bind data using chained bind as described in xref:blazor/components/data-binding. Nested and un-nested components can share access to data using a registered in-memory state container. A custom state container class can use an assignable xref:System.Action to notify components in different parts of the app of state changes. In the following example:

  • A pair of components uses a state container to track a property.
  • The components of the example are nested, but nesting isn't required for this approach to work.

StateContainer.cs:

public class StateContainer
{
    public string Property { get; set; } = "Initial value from StateContainer";

    public event Action OnChange;

    public void SetProperty(string value)
    {
        Property = value;
        NotifyStateChanged();
    }

    private void NotifyStateChanged() => OnChange?.Invoke();
}

In Program.Main (Blazor WebAssembly):

builder.Services.AddSingleton<StateContainer>();

In Startup.ConfigureServices (Blazor Server):

services.AddSingleton<StateContainer>();

Pages/Component1.razor:

@page "/Component1"
@inject StateContainer StateContainer
@implements IDisposable

<h1>Component 1</h1>

<p>Component 1 Property: <b>@StateContainer.Property</b></p>

<p>
    <button @onclick="ChangePropertyValue">Change Property from Component 1</button>
</p>

<Component2 />

@code {
    protected override void OnInitialized()
    {
        StateContainer.OnChange += StateHasChanged;
    }

    private void ChangePropertyValue()
    {
        StateContainer.SetProperty($"New value set in Component 1: {DateTime.Now}");
    }

    public void Dispose()
    {
        StateContainer.OnChange -= StateHasChanged;
    }
}

Shared/Component2.razor:

@inject StateContainer StateContainer
@implements IDisposable

<h2>Component 2</h2>

<p>Component 2 Property: <b>@StateContainer.Property</b></p>

<p>
    <button @onclick="ChangePropertyValue">Change Property from Component 2</button>
</p>

@code {
    protected override void OnInitialized()
    {
        StateContainer.OnChange += StateHasChanged;
    }

    private void ChangePropertyValue()
    {
        StateContainer.SetProperty($"New value set in Component 2: {DateTime.Now}");
    }

    public void Dispose()
    {
        StateContainer.OnChange -= StateHasChanged;
    }
}

The preceding components implement xref:System.IDisposable, and the OnChange delegates are unsubscribed in the Dispose methods, which are called by the framework when the components are disposed. For more information, see xref:blazor/components/lifecycle#component-disposal-with-idisposable.