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

.NET 8 MAUI Blazor子组件重渲染后数据无法重置问题求助

问题描述

开发基于.NET 8的MAUI Blazor应用时遇到组件数据重置问题:嵌套的ManageTags组件中,对数据进行增删修改后,未提交更改时点击父页面的「Search (FakeAPI)」按钮想要重置为初始数据,但ManageTags内的私有字段_localItem依然保留修改后的内容,没有被重置。

问题原因

Blazor组件实例默认会被复用,只有当组件的@key值变化时才会重新创建实例。父页面点击搜索按钮更新_data时,ManageTags组件只是触发重渲染,但组件实例并未销毁,因此私有字段_localItem的状态会被保留,不会自动重置。

解决方案

以下是几种可行的解决方式:

方法一:监听参数变化重置本地数据

在ManageTags组件中重写SetParametersAsync方法,监听_datas参数的变化,当参数更新时清空_localItem:

@code {
    [Parameter]
    public List<Data> _datas { get; set; }
    [Parameter]
    public EventCallback<Data> OnAdd { get; set; }
    [Parameter]
    public EventCallback<Data> OnRemove { get; set; }

    private List<Data> _localItem { get; set; } = new List<Data>();

    private Modal modal = default!;

    // 重写参数设置方法,监听_datas变化
    public override async Task SetParametersAsync(ParameterView parameters)
    {
        var oldDatas = _datas;
        await base.SetParametersAsync(parameters);
        
        // 当_datas引用变化时,重置本地数据
        if (!ReferenceEquals(oldDatas, _datas))
        {
            _localItem.Clear();
        }
    }

    // 其他原有方法保持不变
    private async Task OnHideModalClick()
    {
        await modal.HideAsync();
    }

    private async Task OnShowModalClick()
    {
        await modal.ShowAsync();
    }

    private async Task Add()
    {
        Random rnd = new Random();
        int num = rnd.Next();
        var item = new Data { Age = num, Id = num, Name = num.ToString() };
        await OnAdd.InvokeAsync(item);
        _localItem.Add(item);
    }

    private async Task Remove(Data item)
    {
        _localItem.Remove(item);
        await OnRemove.InvokeAsync(item);
    }
}

方法二:使用@key强制组件重新实例化

在父页面引用ManageTags组件时添加@key属性,将_data作为key值,这样每次_data更新时,组件会重新创建实例,_localItem会被重新初始化:

@page "/counter"
@inject IFakeApi FakeApi

<PageTitle>Manage users</PageTitle>

<button @onclick="Search">Search (FakeAPI)</button>

@if(_data is not null)
{
    @foreach(var item in _data)
    {
        <p>@item.Id - @item.Age - @item.Name </p> 
    }
}

<!-- 添加@key="_data"强制组件刷新 -->
<BlazorApp2.Components.ManageTags _datas="_data" OnAdd="OnAdd" OnRemove="OnRemove" @key="_data" />


@code {
    private List<Data> _data { get; set; }
    private bool SHowHideResumeNewTags { get; set; } = false;

    private async Task Search()
    {
        _data = FakeApi.GetData();
    }

    public void OnAdd(Data item)
    {
        _data.Add(item);
    }

    public void OnRemove(Data item)
    {
        _data.Remove(item);
    }
}

方法三:父组件主动触发子组件重置

在ManageTags组件中添加一个公开的重置方法,父组件通过组件引用调用该方法:

  1. 在ManageTags组件中添加重置方法:
@code {
    // 其他代码不变

    // 公开重置方法
    public void ResetLocalData()
    {
        _localItem.Clear();
    }
}
  1. 父页面引用组件并调用重置方法:
@page "/counter"
@inject IFakeApi FakeApi

<PageTitle>Manage users</PageTitle>

<button @onclick="Search">Search (FakeAPI)</button>

@if(_data is not null)
{
    @foreach(var item in _data)
    {
        <p>@item.Id - @item.Age - @item.Name </p> 
    }
}

<!-- 添加组件引用 -->
<BlazorApp2.Components.ManageTags @ref="manageTagsComponent" _datas="_data" OnAdd="OnAdd" OnRemove="OnRemove" />


@code {
    private List<Data> _data { get; set; }
    private bool SHowHideResumeNewTags { get; set; } = false;
    // 组件引用
    private BlazorApp2.Components.ManageTags manageTagsComponent;

    private async Task Search()
    {
        _data = FakeApi.GetData();
        // 调用子组件的重置方法
        manageTagsComponent?.ResetLocalData();
    }

    public void OnAdd(Data item)
    {
        _data.Add(item);
    }

    public void OnRemove(Data item)
    {
        _data.Remove(item);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 16:38:18