何时在 Blazor 组件中调用 StateHasChanged()

1 asp.net blazor

我试图弄清楚何时需要调用 StateHasChanged()。我知道当通过 Javascript 更改值时,可能需要强制 blazor 组件呈现页面。在下面的代码中,我有一个名为 HandleClick 的方法来处理按钮单击,并且我故意注释掉了 StateHasChanged() 。HandleClick 方法本身调用 Javascript 来设置第 2 部分中的 element 的值。由于 Blazor 组件不知道 fromJs 值的变化,因此第 1 部分中的值在单击后不会更新。但问题是,为什么当我再次单击按钮时,第 1 部分中的值会发生变化。

@page "/ExampleY"

@using Microsoft.AspNetCore.Components
@using Microsoft.JSInterop
@inject IJSRuntime JSRuntime

<div class="p-2">
    <p class="alert-info p-3">
       Part 1.  Get value via JS call: <strong>@(fromJs ?? "Empty")</strong>
    </p>

    <p class="alert-success p-3">
        Part 2. Set value via JS call: <strong @ref="element"></strong>
    </p>

    <button class="btn btn-success" @onclick="HandleClick">Click to Call JS</button>
</div>

@code {
    private string fromJs;
    private ElementReference element;

    public async void HandleClick()
    {
        fromJs = await JSRuntime.InvokeAsync<string>("setText", element, "Hello from JS call!");
        // StateHasChanged();
    }

}
Run Code Online (Sandbox Code Playgroud)

Hen*_*man 5

这与 JavaScript 互操作无关。

当您进行此更改时:

//public async void HandleClick()
  public async Task HandleClick()
Run Code Online (Sandbox Code Playgroud)

那么两个部分将同时更新。

几乎总是回避async void。它是像 Timer.Elapsed 这样的旧式事件处理程序的最后手段。Blazor 事件可以返回void[async] Task

问题是为什么当我再次单击按钮时第 1 部分中的值会发生变化。

ButtonClick 总是会导致重新渲染。但因为async void这可能发生在 分配之前。 fromJs等待await JSRuntime.InvokeAsync(...)允许这样做。下次单击时,您将看到第 1 部分中出现的 fromJs 的先前值。
使用"Hello from JS call! "+DateTime.Now来查看此版本控制的发生。