【问题标题】:how to stop rendering twice (for non-data retrieving components) when using prerendering from _host.cshtml in Blazor?在 Blazor 中使用 _host.cshtml 的预渲染时,如何停止渲染两次(对于非数据检索组件)?
【发布时间】:2021-05-11 17:56:05
【问题描述】:

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

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

此变量将在第二次渲染中恢复为“隐藏”值。请帮助如何防止这种情况发生。

【问题讨论】:

    标签: blazor server-side-rendering blazor-webassembly preloading


    【解决方案1】:

    来自以下网站: Stateful reconnection after prerendering

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

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

    以下代码在基于模板的 Blazor Server 应用中演示了更新的 WeatherForecastService,该应用可避免双重呈现。在以下示例中,等待的延迟 (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();
            });
        }
    }
    

    【讨论】:

    • 你能帮我把它用于非任务返回服务吗?
    • @Keerthi,请发布您正在使用的服务中的示例方法。
    • 嗨@Jason,我在下面发布了我的代码作为答案(让代码看起来正确缩进)。请看一下:)
    【解决方案2】:
    <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

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

    【讨论】:

      猜你喜欢
      • 2020-03-17
      • 1970-01-01
      • 2020-07-14
      • 1970-01-01
      • 2021-10-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-11
      • 2017-11-05
      相关资源
      最近更新 更多