C# Academy · Oppitunti

Tilan hallinta Blazorissa

Hallinnoikaa jaettua tilaa palveluiden singleton-olioilla, Fluxorilla tai periytyvällä AppStatella, jotta käyttöliittymä pysyy yhdenmukaisena komponenteissa.

Oppitunti 4/412 vaihetta

Tilan hallinta Blazorissa on ilmainen C# Academy-oppitunti CoddyKitissä. Tämä on oppitunti 4/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu C# Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. C# Academy-kurssilla on yhteensä 4 oppituntia.

Blazorin tilanhallinnan haasteet

Blazor-sovellusten kasvaessa monien toisistaan riippumattomien komponenttien välillä jaettavan tilan hallinnasta tulee monimutkaista. Yksinkertainen propien ketjutettu välittäminen ei enää riitä, vaan tarvitsette keskitetyn ja reaktiivisen tilavaraston.

Yksinkertainen tila scoped-palvelulla

Yksinkertaisin tapa hallita Blazorin tilaa on scoped-palvelu, joka säilyttää tilan ja tarjoaa tapahtuman, johon komponentit voivat tilata muutoksia.

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

Tilamuutosten seuraaminen

Komponentit tilaavat tilapalvelun OnChanged-tapahtuman ja kutsuvat StateHasChanged-metodia uudelleenrenderöintiä varten. Muistakaa peruuttaa tilaus Dispose-metodissa.

@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 tilasäilönä

Ympäröikää juuriasettelu CascadingValue-elementillä, joka sisältää tilapalvelunne. Kaikki jälkeläiset voivat käyttää sitä ilman, että prop-arvoja tarvitsee välittää erikseen komponenttiketjussa.

@* 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-malli Blazorille

Fluxor tuo Redux-tyylisen yksisuuntaisen tietovuon Blazoriin: tila → komponentti → toiminto → pelkistin → tila. Se sopii erinomaisesti monimutkaisiin sovelluksiin.

// 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));

Fluxorin käyttö komponentissa

Injektoikaa IState<T> tilan lukemista varten ja IDispatcher toimintojen lähettämistä varten. InheritsFrom<FluxorComponent> (tai mixin) tilaa tilamuutokset automaattisesti.

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

Tilauksen säilyttäminen LocalStoragessa

Säilyttäkää tila sivun päivitysten yli selaimen localStoragen avulla JavaScript-yhteentoimivuuden kautta. Palauttakaa tila sovelluksen käynnistyessä.

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

Blazored.LocalStorage-paketti tarjoaa selkeän tyypitetyn rajapinnan selaimen localStorageen ilman, että kirjoitatte JavaScript-yhteentoimivuuskutsuja käsin.

// 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-tila NavigationManagerilla

Käyttäkää kyselyparametreja sellaisen tilan säilyttämiseen, jonka pitää säilyä sivun päivityksen jälkeen ja jonka tulee olla lisättävissä kirjanmerkkeihin. Lukekaa ja kirjoittakaa parametreja NavigationManager-palvelun ja URI-rakentajan avulla.

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

Käytännön esimerkki: ostoskorin tila

Kokonainen malli: tapahtumia tarjoava scoped-tyyppinen CartState-palvelu, joka tallennetaan localStorageen muutoksen yhteydessä ja palautetaan latauksen aikana.

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

Pikatarkistus

Mikä tilanhallintatapa sopii parhaiten yksinkertaiseen Blazor-sovellukseen, jossa jaettua tilaa on vähän?

Kertaus: tilanhallinta Blazorissa

Tärkeimmät asiat:

  • Scoped-palvelu + Action-tapahtuma: yksinkertaisin jaettu tila, joka sopii useimpiin sovelluksiin
  • Juurta ympäröivä CascadingValue tarjoaa koko sovelluksen kattavan pääsyn ilman propien ketjutettua välittämistä
  • Fluxor: Redux-tyylinen yksisuuntainen tietovuo monimutkaiseen tilalogiikkaan
  • Säilyttäkää tila localStoragessa IJSRuntimen tai Blazored.LocalStoragen avulla
  • URL-tila (SupplyParameterFromQuery) kirjanmerkkeihin sopivaa ja jaettavaa käyttöliittymän tilaa varten
  • Peruuttakaa tapahtumien tilaukset aina Dispose-metodissa muistivuotojen estämiseksi
Aloita maksutta

Opi C# tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
93
Oppitunnit
346

Usein kysytyt kysymykset

Onko oppitunti ”Tilan hallinta Blazorissa” ilmainen?

Kyllä – oppitunnin ”Tilan hallinta Blazorissa” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko C# Academy-kurssin, päivitä CoddyKit PROhon. C# Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Tilan hallinta Blazorissa”?

Hallinnoikaa jaettua tilaa palveluiden singleton-olioilla, Fluxorilla tai periytyvällä AppStatella, jotta käyttöliittymä pysyy yhdenmukaisena komponenteissa. Harjoittelet C# Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni C# Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin C# Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 4/4.

Kuinka kauan ”Tilan hallinta Blazorissa”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä C# Academy-oppitunnilla?

Kyllä. Jokainen C# Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Blazor-komponenttimalli
  2. Tietojen sidonta ja tapahtumankäsittely
  3. Komponenttien välinen viestintä ja DI
  4. Tilan hallinta Blazorissa
← Takaisin: C# Academy