通过“交互式服务器渲染模式”和“流式渲染”的组合来防止双重渲染

gen*_*xhd 3 .net asp.net-core blazor blazor-server-side

我正在探索 .NET 8 的新 Blazor 功能,但遇到了一个问题:我的组件似乎渲染了两次。当我将“流渲染”与“交互式服务器渲染模式”结合使用时,会出现此问题。

为了清楚起见,我简化了我的代码:

@attribute [StreamRendering]
@rendermode InteractiveServer

@if (data == null)
{
    <p>Loading...</p>
}
else
{
    <p>@data</p>
}

@code {
   private string? data;

    protected override async Task OnInitializedAsync()
    {
        await Task.Delay(1000);
        data = "Hello World!";
    }
}
Run Code Online (Sandbox Code Playgroud)

在此代码中,我希望首先显示“Loading...”文本,然后在延迟后显示文本“Hello World!” 应该更换它。这是可行的,但是一旦data显示,组件就会重新渲染并且加载文本会再次显示。

我的问题是:

  • 我是对的,第二次重新渲染是因为建立了与服务器的电路连接而发生的?
  • 有没有办法防止第二次重新渲染?

Bri*_*ker 5

data-permanent您可以通过包含数据的元素上的属性来 阻止第一次渲染或告诉渲染引擎不要清除初始数据,这会给人不被渲染两次的感觉。文档

所有交互模式首先在服务器上渲染,然后向客户端发送 html。这通常是一件好事,客户端几乎可以立即看到更新。为了防止“预渲染”,请在构造函数上使用 prerender 参数。

CustomRenderModes.cs

public static class CustomRenderModes
{
    public static readonly InteractiveAutoRenderMode InteractiveAutoRenderModeNoPreRender
        = new InteractiveAutoRenderMode(prerender: false);
    public static readonly InteractiveServerRenderMode InteractiveServerRenderModeNoPreRender
        = new InteractiveServerRenderMode(prerender: false);
    public static readonly InteractiveWebAssemblyRenderMode InteractiveWebAssemblyRenderModeNoPreRender
        = new InteractiveWebAssemblyRenderMode(prerender: false);
}

Run Code Online (Sandbox Code Playgroud)

_imports.razor

@using static {NamespaceOfStaticModelHere}.CustomRenderModes
Run Code Online (Sandbox Code Playgroud)

您可以@(new InteractiveWebAssemblyRenderMode(prerender: false))直接在您的组件上使用。我用静态类展示的方法与 MS 如何使用预渲染设置初始 3 个渲染模式相同。来源

SomeComponent.razor

@page "/thread/{ThreadId}"
@attribute [Authorize]
@rendermode InteractiveWebAssemblyRenderModeNoPreRender
Run Code Online (Sandbox Code Playgroud)

文档