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;