StateHasChanged() 不重新加载页面
StateHasChanged() does not reload page
问题:
如标题中所述,StateHasChanged 不 re-render 页面
Objective:
我想在点击按钮时刷新页面
当前代码
<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();
}
}
仅作记录,我在答案中添加我的评论:
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();
}
}
一方面,您告诉编译器她应该为 click 事件创建一个名为 CreatePlayer: @onclick="CreatePlayer
的事件处理程序。此属性编译器指令在幕后为您创建一个 EventCallback<Task>
处理程序,其含义是您根本不需要在代码中使用 StateHasChanged,因为此方法 ( StateHasChanged ) 在 UI 事件发生。
另一方面,您告诉编译器按钮的类型应设置为"submit"。这当然是错误的……你不能两者兼得。将 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;
问题:
如标题中所述,StateHasChanged 不 re-render 页面
Objective:
我想在点击按钮时刷新页面
当前代码
<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();
}
}
仅作记录,我在答案中添加我的评论:
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();
}
}
一方面,您告诉编译器她应该为 click 事件创建一个名为 CreatePlayer: @onclick="CreatePlayer
的事件处理程序。此属性编译器指令在幕后为您创建一个 EventCallback<Task>
处理程序,其含义是您根本不需要在代码中使用 StateHasChanged,因为此方法 ( StateHasChanged ) 在 UI 事件发生。
另一方面,您告诉编译器按钮的类型应设置为"submit"。这当然是错误的……你不能两者兼得。将 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;