Blazor调用StateHasChanged后组件未立即重新渲染如何解决?
Blazor调用StateHasChanged无法立即触发渲染的解决方案
问题原因
Blazor的UI渲染采用批次异步处理机制:调用StateHasChanged()仅会标记组件需要重渲染,不会同步执行渲染流程,所有待执行的渲染操作会等待当前事件处理方法的全部同步逻辑执行完毕后才会统一执行,因此会出现StateHasChanged()后的代码先运行、UI后更新的现象。
解决方法
要实现StateHasChanged()调用后立即完成UI更新再执行后续逻辑,只需在StateHasChanged()后让出当前线程上下文,让Blazor先执行挂起的渲染任务即可,常用方案为调用await Task.Yield()或await Task.Delay(1)。
修改后的代码示例
@if (Collection.Count > 0) { <div> @for (var i = 0; i< Collection.Count; i++) { <button @onclick=@(() => OnDeleteClick())>@Collection[i]</button> } </div> } @code{ private List<string> Collection = new List<string>(); public class DelArgs { public string Text { get; set; } } protected override void OnInitialized() { Collection.Add("Chai"); Collection.Add("Chang"); Collection.Add("Ikura"); Collection.Add("Anna"); } private async Task OnDeleteClick() { Collection.RemoveAt(0); StateHasChanged(); // 让出上下文,优先执行渲染任务 await Task.Yield(); // 执行到此处时UI已经完成更新 Console.WriteLine("Item Deleted!!"); } }
说明
Task.Yield()的作用是强制将当前异步方法的剩余部分排到队列末尾,让调度器先执行已经在等待队列中的高优先级任务(此处就是Blazor的组件渲染任务),UI更新完成后才会回到当前方法继续执行后续代码。- 仅在确实需要依赖UI更新结果再执行后续逻辑的场景下使用该方案,避免不必要的上下文切换影响性能。
内容的提问来源于stack exchange,提问作者Muthukrishnan Kandasamy
相关产品推荐
相关产品推荐

