我正在尝试弄清楚如何在单击按钮后刷新客户端组件。
带有示例的 repo 链接: https://github.com/ovie91/RefreshComponent
站点/测试或从导航菜单测试
所以我有 OnInitializedAsync 方法从 API 检索数据
protected override async Task OnInitializedAsync()
{
result = await (some API Call);
}
然后我有一个连接到按钮的方法
private async void ButtonClick()
{
await (some API Call);
result = null;
this.StateHasChanged(); <--- Doesnt work :<
}
我尝试使用this.StateHasChanged();但没有任何反应。 作为解决方法,我可以强制您再次导航到同一网站,但这会刷新“整个”网站而不是组件。
关于如何处理它有什么想法吗?
整个代码(精简到最少):
@page "/test"
@inject HttpClient Http
@if (result == null)
{
<p>Loading...<p>
}
else
{
@result
<button @onclick="(() => ButtonClick())">Click</button>
}
@code {
private APIObject result;
protected override async Task OnInitializedAsync()
{
result = await (some API Call);
}
private async void ButtonClick()
{
await (some API Call);
result = null;
this.StateHasChanged(); <--- Doesnt work :<
}
}
更新 我想刷新组件,以便再次触发 OnInitializedAsync,这意味着单击按钮后我不必再次运行相同的代码。希望你明白我的意思。
最佳答案
要获得所需的输出,您只需稍微打乱行即可,来自:
private async void ButtonClick()
{
await (some API Call); // UI checks if an update is needed (No)
result = null; // now an update is needed
this.StateHasChanged(); <--- Doesnt work :< // actually: not needed
}
至:
private async Task ButtonClick()
{
result = null; // change the state
//this.StateHasChanged(); // not needed, a request is pending
await (some API Call); // should show '<h3>Loading</h3>' now
}
请注意,当 await
释放线程时,UI 会更新。
但是,从您的回答中我们得到
var APICall = await Http.GetAsync("SomeAPI");
Thread.Sleep(2000);
当Http.GetAsync("SomeAPI");
确实是一个异步调用而不仅仅是一些替代伪代码时,这应该起作用。因为 Thread.Sleep(2000);
真的会卡住一切。
如果您想确定:
private async Task GetData()
{
await Task.Delay(1); // release the thread for rendering
var APICall = await Http.GetAsync("SomeAPI");
Random rnd = new Random();
Thread.Sleep(2000); // Task.Delay() is much preferred
result = "Random Number: " + rnd.Next();
}
Thread.Sleep()
适合模拟一些 CPU(而非 I/O)密集型代码。所以我并不是说这是错误的,而是要注意其中的区别。
最好使用事件处理程序async Task
而不是async void
,但这不是这里的直接问题。
关于async-await - Blazor 客户端刷新组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62602820/