You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 05:42:03