问题:
如标题中所述,StateHasChanged不会重新呈现页面
目标:
我想在单击按钮时刷新页面
当前代码
<button @onclick="CreatePlayer">Create User</button>
@functions {
string username;
[CascadingParameter]
Task<AuthenticationState> authenticationStateTask { get; set; }
async Task CreatePlayer()
{
var authState = await authenticationStateTask;
var user = authState.User;
var player = await PlayerData.GetByEmail(user.Identity.Name);
if (player == null)
{
player = new Player()
{
Email = user.Identity.Name,
UserName = username
};
await PlayerData.Create(player);
}
await Task.Delay(50);
StateHasChanged();
}
}
答案 0 :(得分:1)
仅作记录,我在评论中添加我的评论:
StateHasChanged
只是通知组件状态有所改变,而不会重新呈现。组件是否必须重新渲染由自己选择。您可以覆盖ShouldRender
来强制组件在状态更改时重新呈现。
@code {
bool _forceRerender;
async Task CreatePlayer()
{
var authState = await authenticationStateTask;
var user = authState.User;
var player = await PlayerData.GetByEmail(user.Identity.Name);
if (player == null)
{
player = new Player()
{
Email = user.Identity.Name,
UserName = username
};
await PlayerData.Create(player);
}
_forceRerender = true;
StateHasChanged();
}
protected override bool ShouldRender()
{
if (_forceRerender)
{
_forceRerender = false;
return true;
}
return base.ShouldRender();
}
}
答案 1 :(得分:1)
一方面,您告诉编译器她应该为 click 事件创建一个事件处理程序,名为CreatePlayer:@onclick="CreatePlayer
。此属性编译器指令在后台为您创建一个EventCallback<Task>
处理程序,其含义是您根本不需要在代码中使用StateHasChanged,因为此方法(StateHasChanged)是在UI之后自动调用的事件发生。
另一方面,您告诉编译器按钮的类型应设置为“提交”。这当然是错误的……你们不能两者兼得。将type属性设置为“ submit”,通常会将表单数据提交到服务器,但是在Blazor中,Blazor的JavaScript部分中的代码阻止了这种方式的工作。是否要向服务器提交表单数据?永远记得Blazor是SPA应用程序。没有提交?
您的代码应为:
<button @onclick="CreatePlayer" >Create User</button>
仅出于记录目的,通常应将AuthenticationStateProvider
对象注入到组件中,如下所示:
@inject AuthenticationStateProvider AuthenticationStateProvider
,然后检索AuthenticationState对象。这是重写代码的方式:
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
var user = authState.User;