0Pricing
C# Academy · Lektion

Zustandsverwaltung in Blazor

Verwalten Sie gemeinsam genutzten Zustand mit Singleton-Diensten, Fluxor oder kaskadierendem AppState, damit die UI über alle Komponenten hinweg konsistent bleibt.

Zustandsverwaltung in Blazor ist eine kostenlose C# Academy-Lektion auf CoddyKit. Dies ist Lektion 4 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des C# Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der C# Academy-Kurs umfasst insgesamt 4 Lektionen.

Herausforderungen der Zustandsverwaltung in Blazor

Wenn Blazor-Anwendungen wachsen, wird die Verwaltung eines Zustands, der von vielen voneinander unabhängigen Komponenten gemeinsam genutzt werden muss, komplex. Einfaches Prop-Drilling reicht dann nicht mehr aus; Sie benötigen einen zentralen, reaktiven Zustandsspeicher.

Einfacher Zustand mit einem Scoped Service

Die einfachste Form der Zustandsverwaltung in Blazor: ein Scoped Service, der den Zustand speichert und ein Ereignis bereitstellt, über das sich Komponenten für Änderungen registrieren können.

public class CartState
{
    private readonly List<CartItem> _items = new();
    public IReadOnlyList<CartItem> Items => _items;
    public int Count => _items.Sum(i => i.Quantity);

    public event Action? OnChanged;

    public void Add(Product p)
    {
        var existing = _items.FirstOrDefault(i => i.ProductId == p.Id);
        if (existing is not null) existing.Quantity++;
        else _items.Add(new CartItem { ProductId = p.Id, Name = p.Name, Price = p.Price });
        OnChanged?.Invoke();
    }
}

Für Zustandsänderungen registrieren

Komponenten registrieren sich für das OnChanged-Ereignis des Zustands-Services und rufen StateHasChanged auf, um sich neu zu rendern. Denken Sie daran, die Registrierung in Dispose wieder aufzuheben.

@inject CartState Cart
@implements IDisposable

<p>Cart: @Cart.Count items</p>

@code {
    protected override void OnInitialized()
    {
        Cart.OnChanged += OnCartChanged;
    }

    private void OnCartChanged()
    {
        InvokeAsync(StateHasChanged);
    }

    public void Dispose() =>
        Cart.OnChanged -= OnCartChanged;
}

CascadingValue als Zustandscontainer

Umschließen Sie Ihr Stammlayout mit einem CascadingValue, das Ihren Zustands-Service enthält. Alle Nachkommen können darauf zugreifen, ohne dass der Zustand explizit durchgereicht werden muss.

@* MainLayout.razor *@
@inject CartState Cart

<CascadingValue Value="Cart">
    @Body
</CascadingValue>

@* Any nested component: *@
@code {
    [CascadingParameter]
    public CartState Cart { get; set; } = default!;

    private void Buy(Product p) => Cart.Add(p);
}

Fluxor: Flux-Muster für Blazor

Fluxor bringt einen unidirektionalen Datenfluss nach dem Redux-Muster in Blazor: State → Component → Action → Reducer → State. Das eignet sich besonders für komplexe Anwendungen.

// dotnet add package Fluxor.Blazor.Web

// State record
[FeatureState]
public record CounterState(int Count = 0);

// Actions
public record IncrementAction(int Amount = 1);

// Reducers
public static class CounterReducers
{
    [ReducerMethod]
    public static CounterState Reduce(CounterState state, IncrementAction action)
        => state with { Count = state.Count + action.Amount };
}

// Registration:
builder.Services.AddFluxor(opt =>
    opt.ScanAssemblies(typeof(Program).Assembly));

Fluxor in einer Komponente verwenden

Injizieren Sie IState<T>, um den Zustand auszulesen, und IDispatcher, um Actions auszulösen. InheritsFrom<FluxorComponent> (oder das Mixin) registriert die Komponente automatisch für Zustandsänderungen.

@inherits FluxorComponent
@inject IState<CounterState> CounterState
@inject IDispatcher Dispatcher

<p>Count: @CounterState.Value.Count</p>
<button @onclick="Increment">+1</button>
<button @onclick="() => Dispatcher.Dispatch(new IncrementAction(5))">+5</button>

@code {
    private void Increment()
        => Dispatcher.Dispatch(new IncrementAction(1));
}

Persistenz mit LocalStorage

Speichern Sie den Zustand über JavaScript-Interop im localStorage des Browsers, damit er bei einer Aktualisierung der Seite erhalten bleibt. Stellen Sie ihn beim Start der Anwendung wieder her.

@inject IJSRuntime JS

@code {
    private async Task SaveStateAsync()
    {
        var json = JsonSerializer.Serialize(_state);
        await JS.InvokeVoidAsync("localStorage.setItem", "appState", json);
    }

    protected override async Task OnInitializedAsync()
    {
        var json = await JS.InvokeAsync<string?>("localStorage.getItem", "appState");
        if (json is not null)
            _state = JsonSerializer.Deserialize<AppState>(json) ?? new();
    }

    private AppState _state = new();
}

Paket Blazored.LocalStorage

Das Paket Blazored.LocalStorage stellt eine übersichtliche, typsichere API für den localStorage des Browsers bereit, ohne dass Sie JavaScript-Interop-Aufrufe von Hand schreiben müssen.

// dotnet add package Blazored.LocalStorage
builder.Services.AddBlazoredLocalStorage();

@inject ILocalStorageService LocalStorage

@code {
    protected override async Task OnInitializedAsync()
    {
        _cart = await LocalStorage.GetItemAsync<List<CartItem>>("cart") ?? new();
    }

    private async Task SaveCartAsync()
    {
        await LocalStorage.SetItemAsync("cart", _cart);
    }

    private List<CartItem> _cart = new();
}

URL-Zustand mit NavigationManager

Verwenden Sie Abfrageparameter für Zustände, die eine Seitenaktualisierung überstehen und als Lesezeichen gespeichert werden können. Lesen und schreiben Sie sie über NavigationManager und den URI-Builder.

@inject NavigationManager Nav
@page "/products"

@code {
    [SupplyParameterFromQuery] public string? Search { get; set; }
    [SupplyParameterFromQuery] public int Page { get; set; } = 1;

    private void UpdateSearch(string s)
    {
        Nav.NavigateTo(
            Nav.GetUriWithQueryParameters(
                new Dictionary<string, object?>
                {
                    [nameof(Search)] = s,
                    [nameof(Page)]   = 1
                }));
    }
}

Praxisbeispiel: Warenkorbzustand

Ein vollständiges Muster: ein Scoped-Service CartState mit Ereignissen, der bei Änderungen im localStorage gespeichert und beim Laden wiederhergestellt wird.

public class CartState
{
    private readonly ILocalStorageService _storage;
    private List<CartItem> _items = new();
    public event Action? OnChanged;

    public CartState(ILocalStorageService storage) => _storage = storage;

    public async Task InitAsync()
    {
        _items = await _storage.GetItemAsync<List<CartItem>>("cart") ?? new();
    }

    public async Task AddAsync(Product p)
    {
        var item = _items.FirstOrDefault(i => i.ProductId == p.Id);
        if (item is not null) item.Quantity++;
        else _items.Add(new CartItem { ProductId = p.Id, Name = p.Name });
        await _storage.SetItemAsync("cart", _items);
        OnChanged?.Invoke();
    }
}

Schnelltest

Welche Form der Zustandsverwaltung eignet sich am besten für eine einfache Blazor-Anwendung mit wenig gemeinsam genutztem Zustand?

Rückblick: Zustandsverwaltung in Blazor

Die wichtigsten Erkenntnisse:

  • Scoped Service + Action-Ereignis: einfachster gemeinsamer Zustand, für die meisten Anwendungen geeignet
  • Ein CascadingValue um das Stammlayout ermöglicht anwendungsweiten Zugriff ohne Prop-Drilling
  • Fluxor: unidirektionaler Datenfluss nach dem Redux-Muster für komplexe Zustandslogik
  • Zustand mit IJSRuntime oder Blazored.LocalStorage im localStorage speichern
  • URL-Zustand (SupplyParameterFromQuery) für als Lesezeichen speicherbaren und teilbaren UI-Zustand
  • Ereignisregistrierungen in Dispose immer aufheben, um Speicherlecks zu vermeiden

Häufig gestellte Fragen

Ist die Lektion „Zustandsverwaltung in Blazor“ kostenlos?

Ja — der vollständige Text von „Zustandsverwaltung in Blazor“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des C# Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der C# Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Zustandsverwaltung in Blazor“?

Verwalten Sie gemeinsam genutzten Zustand mit Singleton-Diensten, Fluxor oder kaskadierendem AppState, damit die UI über alle Komponenten hinweg konsistent bleibt. Du übst C# Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um C# Academy zu starten?

Keine Vorkenntnisse erforderlich. C# Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 4 von 4.

Wie lange dauert die Lektion „Zustandsverwaltung in Blazor“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser C# Academy-Lektion Code schreiben und ausführen?

Ja. Jede C# Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Blazor-Komponentenmodell
  2. Datenbindung und Ereignisbehandlung
  3. Komponentenkommunikation und DI
  4. Zustandsverwaltung in Blazor
← Zurück zu C# Academy