Blazor UI不更新问题:从JavaScript调用C#方法修改值后界面未刷新
问题根因
你使用静态JS互操作调用静态方法更新静态currentCount变量时,Blazor组件的UI更新依赖组件实例调用StateHasChanged()通知渲染树更新,静态方法无法关联到当前Counter组件的实例,因此不会触发UI重绘,就会出现数值更新但界面不变的问题。
解决方案:改用实例级JS互操作
1. 修改Razor组件代码
@page "/counter" @inject IJSRuntime JSRuntime @implements IAsyncDisposable <h1>Counter</h1> <p>Current count: @currentCount</p> <button class="btn btn-primary" @onclick="IncrementMe">Click me</button> @code { // 不要用静态变量,改为实例变量 private int currentCount = 0; // 保存当前组件的DotNet引用,用于传递给JS private DotNetObjectReference<Counter>? _componentRef; protected override async Task OnInitializedAsync() { _componentRef = DotNetObjectReference.Create(this); // 将组件实例注册到JS层 await JSRuntime.InvokeVoidAsync("registerCounterInstance", _componentRef); } public void IncrementMe() { currentCount++; } // 去掉static修饰,改为实例方法 [JSInvokable] public void IncrementCount() { currentCount++; // 手动触发UI重绘 StateHasChanged(); } // 组件销毁时释放引用,避免内存泄漏 public async ValueTask DisposeAsync() { if (_componentRef != null) { await JSRuntime.InvokeVoidAsync("unregisterCounterInstance"); _componentRef.Dispose(); } } }
2. 修改JS代码
let counterInstance = null; // 注册组件实例 window.registerCounterInstance = (instance) => { counterInstance = instance; } // 注销组件实例 window.unregisterCounterInstance = () => { counterInstance = null; } const broadcast = new BroadcastChannel('count-channel'); broadcast.onmessage = (event) => { if (counterInstance) { // 调用实例方法,替换原来的静态调用 counterInstance.invokeMethod('IncrementCount'); console.log("done"); } };
备选方案:静态事件通知(适合多页面同步更新场景)
如果你需要所有打开的Counter页面都同步更新,可以用静态事件做通知,不需要修改原有JS逻辑:
@page "/counter" @implements IDisposable <h1>Counter</h1> <p>Current count: @currentCount</p> <button class="btn btn-primary" @onclick="IncrementMe">Click me</button> @code { static int currentCount = 0; // 定义静态事件 private static event Action? OnCountUpdated; protected override void OnInitialized() { // 组件实例订阅静态事件 OnCountUpdated += StateHasChanged; } public void IncrementMe() { currentCount++; OnCountUpdated?.Invoke(); } [JSInvokable] public static void IncrementCount(string ignore) { currentCount++; // 触发静态事件,通知所有订阅的组件实例更新UI OnCountUpdated?.Invoke(); } public void Dispose() { // 取消订阅,避免内存泄漏 OnCountUpdated -= StateHasChanged; } }
内容的提问来源于stack exchange,提问作者Quinton
相关产品推荐
相关产品推荐

