Home > Software engineering >  StateHasChanged is not Rendering the component when even Action is invoked
StateHasChanged is not Rendering the component when even Action is invoked

Time:08-01

I'm trying to trigger StateHasChanged when the button is clicked. This is done by adding StateHasChanged to event Action. When debugging I can see that the Invoke method of the event is being fired but the UI is not re-rendering.

This is the flow I want it work like:

  1. The button is clicked in OgToolbar.razor.cs
  2. The event is triggered
  3. StorageManagerService changes the state in the local storage and invokes the event
  4. The UI is re-rendering in OgSidebar.razor.cs

OgSidebar.razor.cs where the UI must re-render

protected override void OnInitialized()
{
     StorageManagerService.OnChange  = StateHasChanged;
}

protected override async Task OnInitializedAsync()
{
    var containsKey = await StorageManagerService.ContainsKeyAsync("isSidebarToggled");

    if (containsKey == false)
        await StorageManagerService.SetItemAsync("isSidebarToggled", true);

    _isSidebarToggled = await StorageManagerService.GetItemByKeyAsync<bool> 
                        ("isSidebarToggled");
}

public void Dispose()
{
    StorageManagerService.OnChange -= StateHasChanged;
}

OgToolbar.razor.cs where the button is clicked and triggers the event

[Inject]
private IStorageManagerService StorageManagerService { get; set; }

private bool _isSidebarToggled = false;

protected override void OnInitialized()
{
    StorageManagerService.OnChange  = StateHasChanged;
}

protected override async Task OnInitializedAsync()
{
    var containsKey = await StorageManagerService.ContainsKeyAsync("isSidebarToggled");

    if (containsKey == false)
        await StorageManagerService.SetItemAsync("isSidebarToggled", true);

    _isSidebarToggled = await StorageManagerService.GetItemByKeyAsync<bool>("isSidebarToggled");
}

public void Dispose()
{
    StorageManagerService.OnChange -= StateHasChanged;
}

StorageManagerService.cs where the state is managed in local storage using Blazored:

private readonly ILocalStorageService _localStorageService;

public event Action OnChange;

public async Task<T> GetItemByKeyAsync<T>(string identifier)
{
    var itemFromLocalStorage = await _localStorageService.GetItemAsync<T>(identifier);

    return itemFromLocalStorage;
}

public async Task<bool> ContainsKeyAsync(string identifier)
{
    return await _localStorageService.ContainKeyAsync(identifier);
}

public async Task SetItemAsync<T>(string identifier,T item)
{
    await _localStorageService.SetItemAsync(identifier, item);

    OnChange.Invoke();
}

CodePudding user response:

You trigger the event but the state of _isSidebarToggled is not refreshed.

Roughly:

//OgSidebar.razor.cs

protected override void OnInitialized()
{
     StorageManagerService.OnChange  = async () => 
       { 
         _isSidebarToggled = await StorageManagerService
            .GetItemByKeyAsync<bool> ("isSidebarToggled");
          StateHasChanged ();
       };
}

Using async void for the eventhandler is a little iffy.

  • Related