Tilstandshåndtering i Blazor
Administrer delt tilstand med singleton-tjenester, Fluxor eller kaskaderende AppState for å holde brukergrensesnittet konsistent på tvers av komponenter.
Tilstandshåndtering i Blazor er en gratis leksjon i C# Academy på CoddyKit. Dette er leksjon 4 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i C# Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i C# Academy inneholder totalt 4 leksjoner.
Utfordringer med tilstandsbehandling i Blazor
Etter hvert som Blazor-apper vokser, blir det komplekst å håndtere tilstand som må deles mellom mange urelaterte komponenter. Enkel prop-drilling fungerer ikke lenger; De trenger et sentralisert, reaktivt tilstandslager.
Enkel tilstand med en scoped-tjeneste
Den enkleste formen for tilstandsbehandling i Blazor er en scoped-tjeneste som inneholder tilstanden og eksponerer en hendelse som komponenter kan abonnere på ved endringer.
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();
}
}Abonnere på tilstandsendringer
Komponenter abonnerer på OnChanged-hendelsen i tilstandstjenesten og kaller StateHasChanged for å gjengi komponenten på nytt. Husk å avslutte abonnementet i Dispose.
@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 som tilstandsbeholder
Pakk inn rotlayouten i en CascadingValue med tilstandstjenesten. Alle etterkommere kan få tilgang til den uten eksplisitt prop-drilling.
@* 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-mønsteret for Blazor
Fluxor bringer en Redux-lignende enveis dataflyt til Blazor: State → Component → Action → Reducer → State. Dette passer godt for komplekse applikasjoner.
// 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));Bruke Fluxor i en komponent
Injiser IState<T> for å lese tilstanden og IDispatcher for å sende handlinger. InheritsFrom<FluxorComponent> (eller mixin-en) abonnerer automatisk på tilstandsendringer.
@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));
}Persistens med localStorage
Bevar tilstanden mellom sideoppdateringer ved å bruke nettleserens localStorage via JavaScript-interoperabilitet. Gjenopprett den når appen starter.
@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();
}Blazored.LocalStorage-pakken
Blazored.LocalStorage-pakken tilbyr et rent, typesikkert API over nettleserens localStorage uten at De må skrive JS interop-kall manuelt.
// 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-tilstand med NavigationManager
Bruk spørringsparametere for å lagre tilstand som skal overleve en sideoppdatering og kunne brukes i bokmerker. Les og skriv dem via NavigationManager og URI-byggeren.
@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
}));
}
}I praksis: Tilstand for handlekurv
Et komplett mønster: en scoped CartState-tjeneste med hendelser, lagret i localStorage ved endringer og gjenopprettet ved innlasting.
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();
}
}Kjapp kontroll
Hvilken tilnærming til tilstandsbehandling passer best for en enkel Blazor-app med begrenset delt tilstand?
Oppsummering: Tilstandsbehandling i Blazor
Viktigste punkter:
- Scoped-tjeneste + Action-hendelse: den enkleste delte tilstanden, og god for de fleste apper
- CascadingValue rundt roten gir tilgang i hele appen uten prop-drilling
- Fluxor: Redux-lignende enveis flyt for kompleks tilstandslogikk
- Bevar tilstanden i localStorage med IJSRuntime eller Blazored.LocalStorage
- URL-tilstand (SupplyParameterFromQuery) for UI-tilstand som kan bokmerkes og deles
- Avslutt alltid abonnementer på hendelser i Dispose for å hindre minnelekkasjer
Lær deg C# med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 93
- Leksjoner
- 346
Ofte stilte spørsmål
Er leksjonen «Tilstandshåndtering i Blazor» gratis?
Ja – hele teksten i «Tilstandshåndtering i Blazor» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av C# Academy-kurset, kan du oppgradere til CoddyKit PRO. Kurset i C# Academy inneholder totalt 4 leksjoner.
Hva lærer jeg i «Tilstandshåndtering i Blazor»?
Administrer delt tilstand med singleton-tjenester, Fluxor eller kaskaderende AppState for å holde brukergrensesnittet konsistent på tvers av komponenter. Du øver på C# Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med C# Academy?
Ingen tidligere erfaring er nødvendig. C# Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 4 av 4.
Hvor lang tid tar leksjonen «Tilstandshåndtering i Blazor»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne C# Academy-leksjonen?
Ja. Alle C# Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- Blazor-komponentmodellen
- Databinding og hendelseshåndtering
- Kommunikasjon mellom komponenter og DI
- Tilstandshåndtering i Blazor