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

Blazor组件更新值后页面未更新问题排查

问题原因分析

这是Blazor组件渲染机制的特性导致的:

  • MyClass是引用类型,子组件修改Param1.IsSet时,只是修改了父子组件共享对象的属性值,父组件的myObj引用本身没有变化,Blazor不会自动检测引用类型内部属性的变更。
  • 当绑定OnSetHandler时,调用OnSet.InvokeAsync()会触发Blazor的组件渲染链更新:EventCallback内部会自动调用父组件的StateHasChanged(),父组件因此重新渲染,读取到myObj.IsSet的新值。
  • 当没有绑定OnSet回调时,子组件修改属性后没有触发父组件的重新渲染逻辑,父组件UI会停留在旧值状态。
解决方案

提供三种可行的解决方式:

1. 让MyClass实现INotifyPropertyChanged

通过属性变更通知机制,让UI自动感知属性变化:

using System.ComponentModel;
using System.Runtime.CompilerServices;

public class MyClass : INotifyPropertyChanged
{
    private bool _isSet;
    public bool IsSet
    {
        get => _isSet;
        set
        {
            if (_isSet != value)
            {
                _isSet = value;
                OnPropertyChanged();
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

修改后,无论是否绑定EventCallback,属性变更都会自动通知UI更新。

2. 强制触发父组件状态更新

在子组件中添加专门的回调,用来通知父组件刷新:
修改MyComponent代码:

<hr />

<h6>MyComponent</h6>

<div>IsSet: @Param1.IsSet</div>
<button type="button" @onclick="SetVal">Set value</button>

<hr />

@code {
    [Parameter] public MyClass Param1 { get; set; }
    [Parameter] public EventCallback OnSet { get; set; }
    // 新增专门通知父组件刷新的回调
    [Parameter] public EventCallback OnPropertyUpdated { get; set; }

    private async Task SetVal()
    {
        Param1.IsSet = true;

        if (OnSet.HasDelegate) await OnSet.InvokeAsync();
        // 强制通知父组件刷新
        await OnPropertyUpdated.InvokeAsync();
    }
}

父组件使用时绑定该回调:

@page "/"

<div>IsSet: @myObj.IsSet</div>

<MyComponent Param1="myObj" OnPropertyUpdated="() => StateHasChanged()"></MyComponent>

@code
{
    private MyClass myObj = new();
}

3. 父组件订阅属性变更事件

基于方案1中实现了INotifyPropertyChanged的MyClass,在父组件中订阅属性变更事件:

@page "/"
@implements IDisposable

<div>IsSet: @myObj.IsSet</div>

<MyComponent Param1="myObj"></MyComponent>

@code
{
    private MyClass myObj = new();

    protected override void OnInitialized()
    {
        myObj.PropertyChanged += (sender, e) => StateHasChanged();
        base.OnInitialized();
    }

    public void Dispose()
    {
        myObj.PropertyChanged -= (sender, e) => StateHasChanged();
    }
}

内容的提问来源于stack exchange,提问作者Disti

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 21:45:28