Search code examples
blazorblazor-client-side

blazor component not updating | core3.0


Trying to use the solution generated by the latest templates.

  • Having a service whih keeps the list of string.
  • injecting the service in both MainLayout.razor and NavMenu.razor
  • The servie has simple methods viz Add, Remove, Items
  • In the MainLayout, using the OnInitializedAsync() adding some items like following

.

protected override async Task OnInitializedAsync()
    {
        await Task.Run(() =>
        {
            this.svc.Add("string one");
            this.svc.Add("string two");
        });
         await Task.Run(() => StateHasChanged());
    }
  • In the html fragment of NavMenu.razor, i am simple trying to print

    @svc.Items.Count

  • With above code i am not seeing the count getting updated/refreshed, i can have another button handler in MainLayout as well to call the svc.Add method , but count does not get updated.

  • Only when i try to have some btn handler in the navMenu.razor the blazor re-renders itself

<button @onclick="SetCurrentTime"> Time </button>
    <h4>@time</h4>
        
    void SetCurrentTime()
            {
                time = DateTime.Now.ToLongTimeString();
            }

github repo for this problem: (hit AddString and counter should increment) https://github.com/pkaushik23/mycodeshares/tree/master/CheckRefreshBlazor

enter image description here


Solution

  • Your NameService should to notify changes. Learn about it on Invoke component methods externally to update state

    For your service code, something like:

    public class StringService
    {
        public event Func<string, Task> Notify;
        public List<string> Names { get; set; } = new List<string>();
        public void Add(string s)
        {
            this.Names.Add(s);
            if (Notify != null)
            {
                await Notify.Invoke(s);
            }            
        }
    }
    

    on your components:

    protected override void OnInitialized()
    {
        this.svc.Notify += OnNotify;
    }
    
    public async Task OnNotify(string s)
    {
        await InvokeAsync(() =>
        {            
            StateHasChanged();
        });
    }