在 Blazor 中使用来自 _host.cshtml 的预渲染时,如何停止渲染两次对于非数据检索组件?

问题描述

我有一些变量在剃刀页面代码段中初始化,当我开始使用应用程序中的 _Host.cshtml 从服务器进行预渲染时,它们初始化了两次。如何在 UI 中加载客户端部件的第二次渲染期间避免这些初始化?

    resolve: {
        fallback: {
            fs: false,path: false,crypto: false
        }
    }

这个变量在第二次渲染中会回到“隐藏”的值。请帮助如何防止这种情况发生。

解决方法

来自以下网站: Stateful reconnection after prerendering

在 RenderMode 为 ServerPrerendered 的 Blazor 服务器应用中,组件最初作为页面的一部分静态呈现。一旦浏览器建立回服务器的 SignalR 连接,组件将再次呈现并进行交互。如果存在用于初始化组件的 OnInitialized{Async} 生命周期方法,则该方法执行两次:

当组件被静态预渲染时。 建立服务器连接后。 这可能会导致最终呈现组件时 UI 中显示的数据发生明显变化。为避免 Blazor 服务器应用中的这种双重渲染行为,请传入一个标识符以在预渲染期间缓存状态并在预渲染后检索状态。

以下代码演示了在基于模板的 Blazor 服务器应用程序中更新的 WeatherForecastService 可避免双重呈现。在以下示例中,等待的 Delay (await Task.Delay(...)) 模拟了从 GetForecastAsync 方法返回数据之前的短暂延迟。

WeatherForecastService.cs

using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Memory;
using BlazorSample.Shared;

public class WeatherForecastService
{
    private static readonly string[] summaries = new[]
    {
        "Freezing","Bracing","Chilly","Cool","Mild","Warm","Balmy","Hot","Sweltering","Scorching"
    };

    public WeatherForecastService(IMemoryCache memoryCache)
    {
        MemoryCache = memoryCache;
    }

    public IMemoryCache MemoryCache { get; }

    public Task<WeatherForecast[]> GetForecastAsync(DateTime startDate)
    {
        return MemoryCache.GetOrCreateAsync(startDate,async e =>
        {
            e.SetOptions(new MemoryCacheEntryOptions
            {
                AbsoluteExpirationRelativeToNow =
                    TimeSpan.FromSeconds(30)
            });

            var rng = new Random();

            await Task.Delay(TimeSpan.FromSeconds(10));

            return Enumerable.Range(1,5).Select(index => new WeatherForecast
            {
                Date = startDate.AddDays(index),TemperatureC = rng.Next(-20,55),Summary = summaries[rng.Next(summaries.Length)]
            }).ToArray();
        });
    }
}
,
<div class="page_body">
    <div class="navbar navbar-expand-lg navbar-light navbar_cs">
        <NavMenu Width="@ScreenWidth" />
    </div>
    <div style="visibility:@isVisible">
        <CarouselBlock imageset="@CDNImages" />
        @Body
    </div>
    <div class="footer">
        <FooterMenu />
    </div>
</div>

上面的代码在MainLayout.razor文件的Html段,下面的代码段。

@inherits LayoutComponentBase
@inject BrowserService Service
@inject CarouselService cs

public int ScreenWidth { get; set; }
private List<string> CDNImages;
 protected override void OnInitialized()
{
    base.OnInitialized();
    try
    {
        isVisible = "visible";
        ScreenWidth = Service.GetDimension().Width;
        Console.WriteLine("initializing");
    }
    catch (Exception e)
    {
        Console.WriteLine("Error occurred " + e.ToString());
    }
}
protected override void OnParametersSet()
{
    base.OnParametersSet();
    CDNImages = cs.GetImages();
    Console.WriteLine("images are set in onParameterSet");
    //   isVisible = "visible";
}

protected override void OnAfterRender(bool firstRender)
{
    base.OnAfterRender(firstRender);
    if (firstRender)
    {
        //  isVisible = "visible";
    }
}

CarouselService.cs 中的方法如下,它为 CarouselBlock 组件提供字符串列表。

 public List<string> GetImages() 
    {
        for (int i = 1; i <= 3; i++)
        {
            paths.Add(FolderPath + Province + "/test" + i + ".png");
        }
        return paths;
    }

这是我在应用程序中登录页面的完整代码,我想要的只是防止页面重新呈现,因为我已经在使用 _Host.cshtml 从服务器预呈现。

这是我用于预渲染的参考: page link

请告诉我如何防止在浏览器中单击刷新按钮时页面的闪烁效果。