Quantcast
Channel: Active questions tagged blazor - Stack Overflow
Viewing all articles
Browse latest Browse all 4839

Blazor auto render mode prerender flicker problem even though pages use persistence

$
0
0

There are two pages in my app:Page1.razor (home) and Page2.razor. There is no problem rendering first page. But when I navigate to second page, there is flicker problem. I put 1000 ms sleep to better see the flickler. Whichever the page, this problem exists.

  1. Open the app
  2. Page1 renders with no problem
  3. Navigate to Page2, flicker problem
  4. Open an incognito browser page
  5. Paste Page2 link
  6. There is no problem rendering Page2
  7. Navigate to Page1, flicker problem

Although using a global InteractiveAutoRender mode (in App.razor) fixes the problem, my app uses no global render mode. I don't want this. I probably miss something in the component lifecycle. Can't figure out what. Anyone can help? Thank you for your time.

Bug produced github repo:https://github.com/kemgn/PersistenceBug

App.razor:

<head>    .    .<ImportMap /><HeadOutlet /></head><body><Routes /><script src="_framework/blazor.web.js"></script></body> 

Page1.razor:

@page "/"@inject HttpClient Http@using System.Text.Json.Serialization@using System.Collections.ObjectModel@using static PersistanceBug.Client.Pages.Page1@rendermode @(new InteractiveAutoRenderMode(true))@inherits PersistentDataComponentBase<Post[]><h3>Page 1 (Home)</h3><p>Calling mock API from: https://jsonplaceholder.typicode.com/posts</p><NavLink href="page2">Go to Page 2</NavLink><ul>    @foreach (var post in posts)    {<li>@post.Title</li>    }</ul>@code {    private Post[] posts = Array.Empty<Post>();    protected override string DataKey => "page1persist";    protected override async Task<Post[]?> LoadDataAsync()    {        Post[]? result = await Http.GetFromJsonAsync<Post[]>("https://jsonplaceholder.typicode.com/posts").ConfigureAwait(true);        return result ?? [];    }    protected override void OnDataLoaded(Post[]? data)    {        if (data is null)            return;        posts = data;    }    protected override Post[]? PrepareDataForPersistence(Post[]? data)    {        return posts?.ToArray();    }}

Page2.razor:

@page "/page2"@inject HttpClient Http@using System.Text.Json.Serialization@using System.Collections.ObjectModel@using static PersistanceBug.Client.Pages.Page2@rendermode @(new InteractiveAutoRenderMode(true))@inherits PersistentDataComponentBase<Comment[]><h3>Page 2</h3><p>Calling mock API from: https://jsonplaceholder.typicode.com/comments</p><NavLink href="/">Go to Page 1</NavLink><ul>    @foreach (var comment in comments)    {<li>@comment.Name</li>    }</ul>@code {    private Comment[] comments = Array.Empty<Comment>();    protected override string DataKey => "page2persist";    protected override async Task<Comment[]?> LoadDataAsync()    {        Comment[]? result = await Http.GetFromJsonAsync<Comment[]>("https://jsonplaceholder.typicode.com/Comments").ConfigureAwait(true);        return result ?? [];    }    protected override void OnDataLoaded(Comment[]? data)    {        if (data is null)            return;        comments = data;    }    protected override Comment[]? PrepareDataForPersistence(Comment[]? data)    {        return comments?.ToArray();    }}

Persistence.cs

using System;using System.Threading.Tasks;using Microsoft.AspNetCore.Components;namespace PersistanceBug.Client.Pages{    public abstract class PersistentDataComponentBase<T> : Microsoft.AspNetCore.Components.ComponentBase, IDisposable    {        [Inject] protected PersistentComponentState ApplicationState { get; set; } = default!;        private PersistingComponentStateSubscription persistingSubscription;        protected T? Data { get; set; }        private bool disposed;        protected abstract string DataKey { get; }        protected abstract Task<T?> LoadDataAsync();        protected abstract void OnDataLoaded(T? data);        protected abstract T? PrepareDataForPersistence(T? data);        protected override async Task OnInitializedAsync()        {            await base.OnInitializedAsync().ConfigureAwait(true);            Thread.Sleep(1000);            persistingSubscription = ApplicationState.RegisterOnPersisting(persistDataAsync);            bool restored = ApplicationState.TryTakeFromJson(DataKey, out T? restoredData);            if (!restored)            {                T? apiData = await LoadDataAsync().ConfigureAwait(false);                OnDataLoaded(apiData);                if (!Equals(Data, default(T)))                {                    Console.WriteLine($"✅ {DataKey} verisi yüklendi");                }            }            else            {                OnDataLoaded(restoredData);            }        }        private Task persistDataAsync()        {            T? dataToStore = PrepareDataForPersistence(Data);            ApplicationState.PersistAsJson(DataKey, dataToStore);            return Task.CompletedTask;        }        public void Dispose()        {            Dispose(disposing: true);            GC.SuppressFinalize(this);        }        protected virtual void Dispose(bool disposing)        {            if (!disposed)            {                if (disposing)                {                    persistingSubscription.Dispose();                }                disposed = true;            }        }        ~PersistentDataComponentBase()        {            Dispose(disposing: false);        }    }}

Viewing all articles
Browse latest Browse all 4839

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>