.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组件中添加一个公开的重置方法,父组件通过组件引用调用该方法:
- 在
ManageTags组件中添加重置方法:
@code { // 其他代码不变 // 公开重置方法 public void ResetLocalData() { _localItem.Clear(); } }
- 父页面引用组件并调用重置方法:
@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
相关产品推荐
相关产品推荐

