C# Academy · Les

Statebeheer in Blazor

Beheer gedeelde state met service-singletons, Fluxor of cascading AppState om de UI tussen componenten consistent te houden.

Les 4 van 412 stappen

Statebeheer in Blazor is een gratis C# Academy-les op CoddyKit. Dit is les 4 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject C# Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus C# Academy bevat in totaal 4 lessen.

Uitdagingen bij statusbeheer in Blazor

Naarmate Blazor-toepassingen groeien, wordt het complex om status te beheren die door veel niet-gerelateerde componenten moet worden gedeeld. Het eenvoudig doorgeven van parameters schiet tekort; je hebt een gecentraliseerde, reactieve statusopslag nodig.

Eenvoudige status met een service met beperkt bereik

De eenvoudigste vorm van statusbeheer in Blazor: een service met een beperkt bereik die de status beheert en een gebeurtenis beschikbaar stelt waarop componenten zich kunnen abonneren om wijzigingen te ontvangen.

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();
    }
}

Abonneren op statuswijzigingen

Componenten abonneren zich op de gebeurtenis OnChanged van de statusservice en roepen StateHasChanged aan om opnieuw te renderen. Vergeet niet om je in Dispose af te melden.

@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 statuscontainer

Wikkel je hoofdindeling in een CascadingValue met je statusservice. Alle onderliggende componenten kunnen deze gebruiken zonder parameters expliciet door te geven.

@* 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-patroon voor Blazor

Fluxor brengt een eenrichtingsstroom van gegevens in Redux-stijl naar Blazor: Status → Component → Actie → Reducer → Status. Ideaal voor complexe toepassingen.

// 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 gebruiken in een component

Injecteer IState<T> om de status te lezen en IDispatcher om acties te verzenden. InheritsFrom<FluxorComponent> (of de mixin) abonneert zich automatisch op statuswijzigingen.

@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));
}

Status bewaren in LocalStorage

Bewaar de status tussen het vernieuwen van pagina's door browser-localStorage via JavaScript-interoperabiliteit te gebruiken. Herstel de status bij het opstarten van de toepassing.

@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();
}

Het pakket Blazored.LocalStorage

Het pakket Blazored.LocalStorage biedt een overzichtelijke, getypeerde API boven op browser-localStorage, zonder dat je zelf JavaScript-interoperabiliteitsaanroepen hoeft te schrijven.

// 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-status met NavigationManager

Gebruik queryparameters voor status die na het vernieuwen van een pagina behouden moet blijven en als bladwijzer moet kunnen worden opgeslagen. Lees en schrijf deze via NavigationManager en de URI-opbouwer.

@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
                }));
    }
}

Uit de praktijk: status van een winkelwagen

Een compleet patroon: een CartState-service met beperkt bereik en gebeurtenissen, die bij wijzigingen in localStorage wordt opgeslagen en bij het laden wordt hersteld.

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();
    }
}

Korte controle

Welke aanpak voor statusbeheer is het meest geschikt voor een eenvoudige Blazor-toepassing met weinig gedeelde status?

Samenvatting: statusbeheer in Blazor

Belangrijkste punten:

  • Service met beperkt bereik + actiegebeurtenis: de eenvoudigste gedeelde status, geschikt voor de meeste toepassingen
  • Een CascadingValue rond de hoofdcomponent biedt toegang voor de hele toepassing zonder parameters via tussenliggende componenten door te geven
  • Fluxor: eenrichtingsstroom in Redux-stijl voor complexe statuslogica
  • Bewaar status in localStorage met IJSRuntime of Blazored.LocalStorage
  • URL-status (SupplyParameterFromQuery) voor UI-status die als bladwijzer kan worden opgeslagen en gedeeld
  • Meld je altijd in Dispose af van gebeurtenissen om geheugenlekken te voorkomen
Gratis beginnen

Leer C# met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
93
Lessen
346

Veelgestelde vragen

Is de les “Statebeheer in Blazor” gratis?

Ja — de volledige tekst van “Statebeheer in Blazor” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus C# Academy wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus C# Academy bevat in totaal 4 lessen.

Wat leer ik in “Statebeheer in Blazor”?

Beheer gedeelde state met service-singletons, Fluxor of cascading AppState om de UI tussen componenten consistent te houden. Je oefent met C# Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met C# Academy te beginnen?

Ervaring vooraf is niet nodig. C# Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 4 van 4.

Hoe lang duurt de les “Statebeheer in Blazor”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over C# Academy?

Ja. Elke les over C# Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. Blazor-componentmodel
  2. Databinding en gebeurtenisafhandeling
  3. Communicatie tussen componenten en DI
  4. Statebeheer in Blazor
← Terug naar C# Academy