async-awaitblazorlocal-storagemudblazorblazored

Blazored LocalStorage State with MudBlazor initialization / rendering to late


I have a switch that selection is stored as a state. The last state is to be taken out of the state when loading the view. That works.

However, you can see the change of state during rendering. Actually, the view should only be visible when the rendering is finished and you can't see the transition.

Index.razor:

@page "/"

<MudToolBar>
    <MudSwitch T="bool" Checked="Show" CheckedChanged="HandleShowChanged" />
</MudToolBar>

@if (Show)
{
    <h1>Show something</h1>
}
else
{
    <h1>Nothing to show</h1>
}

Index.razor.cs:

public partial class Index
{
    private bool Show { get; set; }

    protected override async Task OnInitializedAsync()
    {
        Show = await LocalStorage.GetItemAsync<bool>(nameof(Show));
    }

    private async Task HandleShowChanged(bool value)
    {
        Show = value;
        await LocalStorage.SetItemAsync(nameof(Show), value);
    }
}

enter image description here

EDIT:

I checked the lifecycle Methods and was confused because OnAfterRenderAsync is called twice which let me understand why I see the transition. Also AfterRender is finished before the end of OnInitializedAsync. This behaiour seems to be correct and is described in microsofts documentation. The solution below is also named there and correct.

Start SetParametersAsync Show: False
Start OnInitializedAsync Show: False
Start OnAfterRenderAsync Show: False
End OnAfterRenderAsync Show: False
End OnInitializedAsync Show: True
Start OnParametersSetAsync Show: True
End OnParametersSetAsync Show: True
Start OnAfterRenderAsync Show: True
End OnAfterRenderAsync Show: True
End SetParametersAsync Show: True

Solution

  • Your problem is that the rendering happens too soon, and that you can't prevent. But you can eliminate the relevant parts until loading is finished:

    @page "/"
    
    @if (isLoaded)
    {
      <MudToolBar>
        <MudSwitch T="bool" Checked="Show" CheckedChanged="HandleShowChanged" />
      </MudToolBar>
    
      @if (Show)
      {
          <h1>Show something</h1>
      }
      else
      {
         <h1>Nothing to show</h1>
      }
    }
    

    I assume you can handle the isLoaded implementation.