Blazor Appstate 不更新 ChildComponent

Blazor Appstate doesn't update ChildComponent

尝试使用 AppState 传递变量 class,当调用发生在同一组件中时组件会更新,但当父级触发事件时不会发生在子组件中。

Parent

@code {
    [Parameter]
    public int Id { get; set; }

    WikiDetailDto wikiDetail = null;

    protected async override Task OnInitializedAsync()
    {
        Console.WriteLine("going in detail INIT");
        AppState.OnCurrentWikiPageChanged += StateHasChanged;
        AppState.SetCurrentWikiPage(await wikiPageService.GetDetail(Id));
        wikiDetail = AppState.CurrentWikiPage;

        Console.WriteLine("Retrieved WikiDetail!");
    }
}

Child

<MudDrawer Anchor="Anchor.End" Open="true">
    <MudDrawerHeader>Recommendations</MudDrawerHeader>
    @if(AppState.CurrentWikiPage != null)
    {
        @(RecommendedWikiPages = CalculateReccomendedWikis(AppState.CurrentWikiPage));
        if(RecommendedWikiPages != null)
        {
            foreach(var p in RecommendedWikiPages)
            {
                <MudCard>
                    <MudCardContent>
                        <MudText>@p.Name</MudText>

                    </MudCardContent>
                </MudCard>
            }
        }
    }
    else
    {
        <p>Loading...</p>
    }

当 AppState.CurrentWikiPage 更新时,它不会检查 cild 的 if 语句。 这里的最佳做法是什么?我不想使用级联值。

AppState

public WikiDetailDto CurrentWikiPage { get; set; }
        public event Action OnCurrentWikiPageChanged;
        public void SetCurrentWikiPage(WikiDetailDto wikiPage)
        {
            CurrentWikiPage = wikiPage;
            OnCurrentWikiPageChanged?.Invoke();
        }

如果我没看错你的代码,child 组件需要注册 OnCurrentWikiPageChanged 事件。

您的 child 需要如下所示:

@implements IDisposable
..... markup code


    protected async override Task OnInitializedAsync()
    {
        AppState.OnCurrentWikiPageChanged += StateHasChanged;
    }

    public void Dispose()
    {
        AppState.OnCurrentWikiPageChanged -= StateHasChanged;
    }

我个人不会 link StateHasChanged 直接到事件处理程序。这是不好的做法,因为 StateHasChanged 必须 运行 UI 上下文线程。如果事件调用者 运行ning 在另一个线程上,您将得到一个异常。我会坚持使用标准 EventHandler。 WASM 现在可能是单线程的,但可能不会永远如此。

我的处理程序看起来像:

private void OnxxxChanged(object sender, EventArgs e)
      => this.InvokeAsync(StateHasChanged);