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
相关产品推荐
相关产品推荐

