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

Blazor组件调用StateHasChanged/this.StateHasChanged无渲染效果问题排查

问题根源

你的导航菜单组件是独立的LayoutComponentBase子类实例,和CategoryAdministration页面属于两个完全隔离的组件对象。你在CategoryAdministration中调用的GetCategoriesNav仅会修改当前页面实例下的NavCategories、NavCategoryPages字段,完全不会同步到布局中的导航菜单组件,因此导航菜单不会触发重渲染。

解决方案(推荐:全局状态通知服务)

这种方式实现简单,适用于跨组件同步状态的场景,没有层级限制:

步骤1:创建状态通知服务

public class CategoryStateService
{
    // 分类数据变更事件
    public event Func<Task> OnCategoryChanged;

    public async Task NotifyChangedAsync()
    {
        if (OnCategoryChanged != null)
        {
            await OnCategoryChanged.Invoke();
        }
    }
}

步骤2:注册服务

在Program.cs中注册服务:

// Blazor WebAssembly 项目注册为单例
builder.Services.AddSingleton<CategoryStateService>();

// Blazor Server 项目注册为 Scoped,避免多用户互相干扰
// builder.Services.AddScoped<CategoryStateService>();

步骤3:导航菜单组件订阅通知

修改你的导航菜单代码:

@inject CategoryStateService CategoryState
@inject CategoryService categoryService
@inject CategoryPageService categoryPageService
@implements IAsyncDisposable

@* 渲染部分不变,建议优化循环逻辑见下文 *@

@code
{
    private List<Category> NavCategories = new List<Category>();
    private List<CategoryPage> NavCategoryPages = new List<CategoryPage>();

    protected override async Task OnInitializedAsync()
    {
        await GetCategoriesNav();
        // 订阅分类变更通知
        CategoryState.OnCategoryChanged += GetCategoriesNav;
    }

    public async Task GetCategoriesNav()
    {
        NavCategories = await categoryService.GetCategories();
        NavCategoryPages = await categoryPageService.GetCategoryPages();
        // 拉取数据后主动触发重渲染
        StateHasChanged();
    }

    // 组件销毁时取消订阅,避免内存泄漏
    public async ValueTask DisposeAsync()
    {
        CategoryState.OnCategoryChanged -= GetCategoriesNav;
    }
}

步骤4:增改分类后触发通知

修改CategoryAdministration中的代码,增改成功后不用调用本地的GetCategoriesNav,直接发通知即可:

@inject CategoryStateService CategoryState

// 新增分类逻辑
async Task AddCategory()
{
    Category thisCategory = new();
    var param = new DialogParameters { ["category"] = thisCategory };
    IDialogReference dialog = DialogService.Show<CategoryDialog>("Add Category", param);
    DialogResult result = await dialog.Result;
    if(!result.Cancelled)
    {
        GetCategories();
        // 触发全局通知,导航菜单会自动拉取最新数据刷新
        await CategoryState.NotifyChangedAsync();
    }
}

// 编辑分类逻辑同理
async Task EditCategory(Category category)
{
    category = await categoryService.EditCategory(category);
    var param = new DialogParameters { ["category"] = category };
    var dialog = DialogService.Show<CategoryDialog>("Edit Category", param);
    DialogResult result = await dialog.Result;
    if (!result.Cancelled)
    {
        GetCategories();
        await CategoryState.NotifyChangedAsync();
    }
}

额外优化:修复导航菜单重复渲染问题

你当前的导航菜单循环逻辑存在冗余嵌套,会导致同一个分类重复渲染多次,优化后的渲染代码:

<MudNavMenu Style="color:white">
@foreach (Category category in NavCategories)
{
    var currentCategoryPages = NavCategoryPages.Where(p => p.CategoryId == category.Id).ToList();
    if(currentCategoryPages.Any())
    {
        <MudNavGroup Title=@category.Name>
            @foreach(CategoryPage page in currentCategoryPages)
            {
                <MudNavLink>@page.PageName</MudNavLink>
            }
        </MudNavGroup>
    }
    else
    {
        <MudNavLink>@category.Name</MudNavLink> 
    }
}
</MudNavMenu>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 23:36:01