How to prevent code in OnInitializedAsync run twice

SandeepG 41 Reputation points
2023-01-13T06:07:02.0866667+00:00

Hi Team,

I understand that the event OnInitializedAsync() executes twice due to prerending. Is there a flag I can use to check if this is a pre-render event or the actual event.

I am just looking for a simple event where I can initialize the default values of my objects.

Thanks.

Blazor
Blazor
A free and open-source web framework that enables developers to create web apps using C# and HTML being developed by Microsoft.
1,403 questions
0 comments No comments
{count} votes

Accepted answer
  1. Zhi Lv - MSFT 32,021 Reputation points Microsoft Vendor
    2023-01-13T08:19:30.2366667+00:00

    Hi @SandeepG

    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.

    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 Microsoft.Extensions.Caching.Memory;
    
    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();
            });
        }
    }
    

    More detail information, see Stateful reconnection after prerendering.

    Besides, you can also try to create a local variable bool dataIsLoaded = false; and only after loading data in OnInitializedAsync you can set it to true. Then in the data check do: @if (dataIsLoaded && Data != null)


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Best regards,

    Dillion

    1 person found this answer helpful.

0 additional answers

Sort by: Most helpful