LocalStorage Kurzeinführung für Blazor

Blazor Web Apps, egal ob Server Rendered oder Webassembly hosted, müssen den Status speichern können. Dabei gibt es die JavaScript API eines Browser LocalStorage und SessionStorage her. Letzteres gilt pro Browser Tab und ersteres auch weiter wenn der Browser geschlossen wurde.

Bei der Suche nach einer Lösung zu Local Storage im Browser, findet man u.a. ein Nuget Paket Microsoft.AspNetCore.ProtectedBrowserStorage, mit wenigen hundert Downloads. Dabei geht es doch viel einfacher. Zuerst benötigt man JavaScript (ja richtig gelesen – auch mit Blazor) Interop. Dazu wird in der Blazor Komponente (Page) das passende DI Objekt referenziert.

   1:  @inject IJSRuntime JSRuntime;

Eine JavaScript Methode kann per InvokeAsnyc aufgerufen werden. Eine beliebige Anzahl von Parametern füllt den JS Aufruf und liefert einen spezifischen Daten Rückgabe Typ. Also aus dem JavaScript Code localStorage.setItem('myCat', 'Tom'); in kombination mit Blazor C# wird

   1:  await JSRuntime.InvokeAsync<string>("localStorage.setItem","daten",MyProperty);

Dies könnte man in einem Button onclick zum speichern aufrufen. Um die Daten wieder zu laden, wird ein getItem API Aufruf benötigt. Einzig Hürde ist, das je nach gewählten prerendering die übliche OnInitializedAsync Methode (entspricht Page load)  zu früh dran ist. Die Anwendung wird einen Fehler auswerfen. Die passende Methode OnAfterRender bieten zusätzlich die Eigenschaft firstRender (sozusagen das IsPostback). Die Reihenfolge der Page Livecycle Events erfordert die Abfrage unter Umständen.

In diesem speziellen Falle erkennt dann Blazor nicht das sich nach dem Rendern das Shadow Dom geändert hat. Um den refresh des DOM mit dem Delta des Shadow Tree auszulösen braucht es noch das Blazor INotifyPropertyChanged, das hier StateHasChanged heist.

   1:  protected async override Task OnAfterRenderAsync(bool firstRender)
   2:  {
   3:    if (firstRender)
   4:     {
   5:     MyProperty = await JSRuntime.InvokeAsync<string>("localStorage.getItem", "daten");
   6:     StateHasChanged();
   7:     }
   8:  }

Kommentare sind geschlossen