Gestion de l’état dans Blazor
Gérez l’état partagé avec des services singleton, Fluxor ou AppState en cascade afin de conserver une interface cohérente entre les composants.
Gestion de l’état dans Blazor est une leçon C# Academy gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage C# Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours C# Academy comprend 4 leçons au total.
Difficultés de gestion de l’état dans Blazor
À mesure que les applications Blazor grandissent, la gestion de l’état qui doit être partagé entre de nombreux composants sans lien direct devient complexe. La simple transmission de propriétés atteint ses limites ; vous avez besoin d’un gestionnaire d’état centralisé et réactif.
État simple avec un service à portée
La solution de gestion d’état Blazor la plus simple consiste à utiliser un service à portée qui conserve l’état et expose un événement auquel les composants peuvent s’abonner pour être informés des changements.
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();
}
}S’abonner aux changements d’état
Les composants s’abonnent à l’événement OnChanged du service d’état et appellent StateHasChanged pour déclencher un nouveau rendu. Pensez à vous désabonner dans 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 comme conteneur d’état
Entourez votre disposition racine d’un CascadingValue contenant votre service d’état. Tous les descendants peuvent y accéder sans transmission explicite des propriétés.
@* 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 : le modèle Flux pour Blazor
Fluxor apporte à Blazor un flux de données unidirectionnel de style Redux : État → Composant → Action → Réducteur → État. C’est idéal pour les applications complexes.
// 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));Utiliser Fluxor dans un composant
Injectez IState<T> pour lire l’état et IDispatcher pour distribuer des actions. InheritsFrom<FluxorComponent> (ou l’extension correspondante) s’abonne automatiquement aux changements d’état.
@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));
}Persistance dans LocalStorage
Conservez l’état entre les actualisations de page en utilisant le localStorage du navigateur via l’interopérabilité JavaScript. Restaurez-le au démarrage de l’application.
@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();
}Package Blazored.LocalStorage
Le package Blazored.LocalStorage fournit une API propre et typée pour le localStorage du navigateur, sans avoir à écrire manuellement des appels d’interopérabilité JavaScript.
// 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();
}État dans l’URL avec NavigationManager
Utilisez les paramètres de requête pour conserver un état qui doit survivre à une actualisation de page et pouvoir être enregistré dans un favori. Lisez-les et modifiez-les avec NavigationManager et le générateur d’URI.
@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
}));
}
}Cas réel : état d’un panier
Un modèle complet : un service CartState à portée avec des événements, conservé dans le localStorage à chaque changement et restauré lors du chargement.
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();
}
}Vérification rapide
Quelle approche de gestion d’état convient le mieux à une application Blazor simple avec peu d’état partagé ?
Récapitulatif : gestion de l’état dans Blazor
Points clés :
- Service à portée + événement d’action : état partagé le plus simple, adapté à la plupart des applications
- CascadingValue autour de la racine : accès à l’échelle de l’application sans transmission manuelle des propriétés
- Fluxor : flux unidirectionnel de style Redux pour une logique d’état complexe
- Persistez l’état dans le localStorage avec IJSRuntime ou Blazored.LocalStorage
- État dans l’URL (SupplyParameterFromQuery) pour un état d’interface pouvant être enregistré dans un favori et partagé
- Désabonnez-vous toujours des événements lors de la libération des ressources afin d’éviter les fuites mémoire
Questions Fréquemment Posées
La leçon « Gestion de l’état dans Blazor » est-elle gratuite ?
Oui — le texte complet de « Gestion de l’état dans Blazor » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours C# Academy, passe à CoddyKit PRO. Le cours C# Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Gestion de l’état dans Blazor » ?
Gérez l’état partagé avec des services singleton, Fluxor ou AppState en cascade afin de conserver une interface cohérente entre les composants. Tu pratiques C# Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer C# Academy ?
Aucune expérience préalable n'est requise. C# Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.
Combien de temps prend la leçon « Gestion de l’état dans Blazor » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon C# Academy ?
Oui. Chaque leçon C# Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Modèle de composants Blazor
- Liaison de données et gestion des événements
- Communication entre composants et DI
- Gestion de l’état dans Blazor