繁体   English   中英

StateHasChanged 用于特定组件,而不是重新渲染页面中的所有组件

[英]StateHasChanged for specific component instead rerender all components in a page

我正在使用多个组件是我的应用程序每个都以有条件的方式呈现。 是否有可能单独重新渲染特定组件?

MyRazor.razor文件,

 <button @onclick="Chnage">Second</button>
<div>
    @if (renderOne)
    {
        var data1 = Count++;
        <ComponentFirst>@data1</ComponentFirst>
    }
    @if (renderTwo)
    {
        var data2 = Count2++;
        <ComponentSecond class="btn-danger">@data2</ComponentSecond>
     }
</div>
@code { 
    void Chnage()
    {
        renderOne = true;
    }
}

ComponentFirst 和 ComponentSecond 通过各自的布尔值检查来呈现。 在按钮单击中,我单独启用了 CompoenentFirst。 但是 ComponentSecond 也再次渲染。 我的目标是如果我单独启用 renderOne ComponentFirst 应该再次渲染。 如果我禁用 renderTwo ComponentTwo 应该再次渲染,而不是渲染两个组件以在应用程序中进行一次更改。

您可能不应该担心组件渲染很多次。 渲染只构建一个渲染树,它不会更新浏览器的 DOM。 只有在构建了整个页面的渲染树后,Blazor 才会将其与最后一个渲染树进行比较,然后从差异中更新 DOM。

话说回来:

如果父组件通过[Parameter]属性(包括RenderFragment )将任何信息传递给子组件,那么每当父组件重新渲染时,子组件也将重新渲染,以防万一发生任何变化。

如果您希望组件独立于其父组件重新渲染,那么您不应将任何 state 传递给它们。 您可以通过将 state 存储在组件外部来实现此目的。 例如

public class MyState
{
  public int Count1 { get; set; }
  public int Count2 { get; set; }

  public event EventHandler<EventArgs> Changed;
  public void NotifyChanged() => Changed?.Invoke(this, EventArgs.Empty);
}

如果您将其注册为可注入依赖项,则可以直接在子组件中使用它

@inject MyState State
@implements IDisposable

<div>
  The value is @State.Count1
</div>

@code
{
  protected override void OnInitialized()
  {
    State.Changed += DoUpdate;
  }

  void IDisposable.Dispose()
  {
    State.Changed -= DoUpdate; // Important1
  }

  private void DoUpdate(object sender, EventArgs e)
  {
    InvokeAsync(StateHasChanged);
  }
}

任何组件都可以通过注入MyState然后执行更新 state

injectedState.Counter1++;
injectedState.Counter2--;
injectedState.NotifyChanged();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM