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

Blazor单例服务注入组件层级后页面未重新渲染问题

问题根源

你的问题出在MyService没有实现属性变更通知机制。Blazor组件不会自动监听普通类的属性变化:点击Component1的按钮修改Counter后,Index组件根本不知道数据已经更新,自然不会触发重新渲染;而Clear Count能生效,只是因为你手动调用了StateHasChanged()强制刷新了Index组件。

解决方案

通过让服务实现INotifyPropertyChanged接口,让属性变化时主动通知所有订阅的组件,实现自动渲染更新。

1. 改造MyService,添加属性变更通知

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

namespace Injection.Pages
{
    public class MyService : INotifyPropertyChanged
    {
        private int _counter;
        public int Counter
        {
            get => _counter;
            set
            {
                if (_counter != value)
                {
                    _counter = value;
                    OnPropertyChanged();
                }
            }
        }

        public void increaseCount()
        {
            Counter += 1;
        }

        public void clearCounter()
        {
            Counter = 0;
        }

        public event PropertyChangedEventHandler PropertyChanged;

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

2. 修改Index组件,订阅服务的变更通知

让Index组件监听服务的PropertyChanged事件,当Counter变化时自动刷新:

@page "/"
@inject MyService myService
@implements IDisposable

<h3>Injection</h3>

<button @onclick="clearCounter">Clear Count</button>
<br />
<br />

@myService.Counter

<Component1 myService="myService" />

@code
{
    protected override void OnInitialized()
    {
        // 订阅Counter属性变更事件
        myService.PropertyChanged += (sender, args) =>
        {
            if (args.PropertyName == nameof(MyService.Counter))
            {
                StateHasChanged();
            }
        };
    }

    private void clearCounter ()
    {
        myService.clearCounter();
        // 现在不需要手动调用StateHasChanged(),属性变更通知会自动触发刷新
    }

    // 组件销毁时取消订阅,避免内存泄漏
    public void Dispose()
    {
        myService.PropertyChanged -= (sender, args) =>
        {
            if (args.PropertyName == nameof(MyService.Counter))
            {
                StateHasChanged();
            }
        };
    }
}

3. 优化Component1组件(可选)

Component1本身没有绑定Counter的显示,所以点击按钮后不需要调用StateHasChanged():

<h3>Component1</h3>

<button @onclick="increaseCount">Increase Count</button>

@code {
    [Parameter]
    public MyService myService { get; set; }

    private void increaseCount()
    {
        myService.increaseCount();
        // 移除不必要的StateHasChanged()调用
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 14:15:07