1

I have some variables that initialize in the code segment in a razor page and they are initializing twice when I started doing the prerendering from the server using _Host.cshtml in the application. How can I avoid these initializations during the second render from the client part loading in UI?

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

This variable is going back to the value "hidden" in the second rendering. Please help how can this be prevented.

2 Answers 2

4

From the following site: Stateful reconnection after prerendering

In a Blazor Server app when RenderMode is ServerPrerendered, the component is initially rendered statically as part of the page. Once the browser establishes a SignalR connection back to the server, the component is rendered again and interactive. If the OnInitialized{Async} lifecycle method for initializing the component is present, the method is executed twice:

When the component is prerendered statically. After the server connection has been established. This can result in a noticeable change in the data displayed in the UI when the component is finally rendered. To avoid this double-rendering behavior in a Blazor Server app, pass in an identifier to cache the state during prerendering and to retrieve the state after prerendering.

The following code demonstrates an updated WeatherForecastService in a template-based Blazor Server app that avoids the double rendering. In the following example, the awaited Delay (await Task.Delay(...)) simulates a short delay before returning data from the GetForecastAsync method.

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();
        });
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

can you please help me in using this for a non-task returning service?
@Keerthi, please post an example method from the service you are working on.
Hi @Jason, I posted my code as an answer in the following(to let the code look properly indented). Kindly take a look at it :)
0
<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>

the above code is in the Html segment of the MainLayout.razor file and the following in the code segment.

@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";
    }
}

The method in CarouselService.cs is the following and it provides the string list to the CarouselBlock component.

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

This is my entire code for the landing page in the application and all I want is to prevent the page from re-rendering as I'm already using _Host.cshtml to pre-render from the server.

this is the reference that I used for pre-rendering: page link

Please let me know how can I prevent the flickering effect of the page when the refresh button is clicked in the browser.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.