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

3.1 KiB

no-loc
Home
Privacy
Kestrel
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.
  • One component in the following example is nested in the other component, but nesting isn't required for this approach to work.

StateContainer.cs:

using System;

public class StateContainer
{
    private string savedString;

    public string Property
    {
        get => savedString;
        set
        {
            savedString = value;
            NotifyStateChanged();
        }
    }

    public event Action OnChange;

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

In Program.Main (Blazor WebAssembly):

builder.Services.AddSingleton<StateContainer>();

In Startup.ConfigureServices (Blazor Server):

services.AddScoped<StateContainer>();

Shared/Nested.razor:

@implements IDisposable
@inject StateContainer StateContainer

<h2>Nested component</h2>

<p>Nested component Property: <b>@StateContainer.Property</b></p>

<p>
    <button @onclick="ChangePropertyValue">
        Change the Property from the Nested component
    </button>
</p>

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

    private void ChangePropertyValue()
    {
        StateContainer.Property = 
            $"New value set in the Nested component: {DateTime.Now}";
    }

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

Pages/StateContainer.razor:

@page "/state-container"
@implements IDisposable
@inject StateContainer StateContainer

<h1>State Container component</h1>

<p>State Container component Property: <b>@StateContainer.Property</b></p>

<p>
    <button @onclick="ChangePropertyValue">
        Change the Property from the State Container component
    </button>
</p>

<Nested />

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

    private void ChangePropertyValue()
    {
        StateContainer.Property = 
            $"New value set in the State Container component: {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-and-iasyncdisposable.