Blazor Server中Blazored.Toast通知重复显示问题求助
问题排查与解决方案
核心原因分析
Toast消息重复显示,大概率是以下两种场景导致:
- Blazor Server预渲染机制:若项目启用预渲染,组件会在服务器端先执行一次
OnInitializedAsync,客户端初始化时又执行一次,触发两次Toast调用。 - 组件意外重建:路由参数变化、子组件状态触发父组件销毁重建,会再次执行
OnInitializedAsync方法。
修复方案
1. 添加单次执行标志位
在组件内新增布尔变量,确保Toast仅被调用一次:
@code { [Parameter] public Guid CustomerId { get; set; } public Guid AddressId { get; set; } public Customer Customer { get; set; } // 新增标志位,控制Toast仅显示一次 private bool _toastShown = false; protected async override Task OnInitializedAsync() { // 使用using自动释放DbContext,避免连接泄漏 using var db = Context.CreateDbContext(); this.Customer = await db.Customers.FindAsync(this.CustomerId); this.AddressId = this.Customer.AddressId.Value; // 仅在未显示过时触发Toast if (!_toastShown) { ShowToaster(); _toastShown = true; } await Task.CompletedTask; } public void ShowToaster() { ToastService.ShowInfo(Toastr.MessageContent(Toastr.MessageType.EmailHasBeenSent), "We'll be in touch soon"); } }
2. 处理预渲染场景(若项目启用)
如果项目开启了预渲染,需要判断当前是否处于浏览器环境,避免服务器端渲染时触发Toast:
@inject IJSRuntime JS // ... public async Task ShowToaster() { // 判断是否在浏览器环境中执行 var isBrowser = await JS.InvokeAsync<bool>("eval", "typeof window !== 'undefined'"); if (isBrowser) { ToastService.ShowInfo(Toastr.MessageContent(Toastr.MessageType.EmailHasBeenSent), "We'll be in touch soon"); } }
3. 排查子组件触发的重建问题
检查CustomerManagerComponent和AddressManagerService(组件名带Service易混淆,建议改为AddressManagerComponent)是否存在触发父组件状态变化的逻辑。若父组件被意外销毁重建,可通过ShouldRender控制渲染时机:
protected override bool ShouldRender() { // 仅当核心数据变化时才重新渲染 return Customer != null && AddressId != default; }
额外优化提示
- 原代码中
DbContext未手动释放,需用using语句包裹,避免数据库连接泄漏。 AddressManagerService命名不符合组件命名规范,建议调整为组件类命名格式,避免与服务类混淆。
内容的提问来源于stack exchange,提问作者Richard Baker
相关产品推荐
相关产品推荐

