Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PersistComponentState inconsistent behavior #51583

Closed
1 task done
Markz878 opened this issue Oct 23, 2023 · 5 comments
Closed
1 task done

PersistComponentState inconsistent behavior #51583

Markz878 opened this issue Oct 23, 2023 · 5 comments
Labels
area-blazor Includes: Blazor, Razor Components ✔️ Resolution: Answered Resolved because the question asked by the original author has been answered. question Status: Resolved

Comments

@Markz878
Copy link

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

I migrated a Blazor hosted WASM app to use .NET 8, and noticed that my database was called twice when navigating to a page that uses WASM render mode and state persistence from a server rendered page. When the page is navigated directly to (or browser is refreshed when on the page), the state persist mechanism works as expected, the database is hit only once, and the markup for state persistence (Blazor-WebAssembly-Component-State) disappears after WASM kicks in.

But after I navigate to another server rendered page and back, the OnInitialized method runs twice without using the state persistance mechanism. This seems like a bug, and puts extra load on the database.

Expected Behavior

I would expect that the state persistence mechanism would behave similarly when navigating between server rendered and interactive WASM pages, and when navigating directly to the interactive page.

Steps To Reproduce

Create new Blazor 8 project with WASM interactivity on per page basis and with sample pages.

Put this code on the Counter page on the Client project:

@page "/counter"
@implements IDisposable
@attribute [RenderModeInteractiveWebAssembly]
<PageTitle>Counter</PageTitle>

<h1>Counter</h1>

<p role="status">Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;
    [Inject] public required PersistentComponentState PersistentComponentState { get; init; }
    private PersistingComponentStateSubscription stateSubscription;
    protected override void OnInitialized()
    {
        stateSubscription = PersistentComponentState.RegisterOnPersisting(PersistData);
        if (PersistentComponentState.TryTakeFromJson(nameof(currentCount), out int count))
        {
            currentCount = count;
            Console.WriteLine("Took count from STORAGE");
        }
        else
        {
            currentCount = 5;
            Console.WriteLine("Took count from SERVICE");
        }
    }

    private Task PersistData()
    {
        PersistentComponentState.PersistAsJson(nameof(currentCount), currentCount);
        return Task.CompletedTask;
    }

    private void IncrementCount()
    {
        currentCount++;
    }

    public void Dispose()
    {
        stateSubscription.Dispose();
    }
}

Run the app and observe the browser Console tab and the application terminal.

When the Counter page is first navigated to, the terminal says "Took count from SERVICE", and the browser says "Took count from STORAGE", which is how it's supposed to work. Same thing happens if the browser is refreshed. Also, the "Blazor-WebAssembly-Component-State" markup disappears.

But when navigating to Home and back to Counter, both say "Took count from SERVICE". This means that the state persistence was not used, and the "database" was hit twice. Also, the "Blazor-WebAssembly-Component-State" markup stays on the page.

Exceptions (if any)

No response

.NET Version

8.0.100-rc.2.23502.2

Anything else?

No response

@dotnet-issue-labeler dotnet-issue-labeler bot added the area-blazor Includes: Blazor, Razor Components label Oct 23, 2023
@javiercn
Copy link
Member

@Markz878 thanks for contacting us.

Persistent component state works in the same way as it does for Blazor Server and WebAssembly. It is only supported as part of the initial render of the components when a runtime (server or webassembly) starts, but it does not work with successive enhanced page navigations.

@javiercn
Copy link
Member

I've filed #51584 with more details for the feature request.

@javiercn javiercn added question ✔️ Resolution: Answered Resolved because the question asked by the original author has been answered. labels Oct 23, 2023
@ghost ghost added the Status: Resolved label Oct 23, 2023
@Markz878
Copy link
Author

Okay great, any chance this would come in .NET 8?

@Markz878
Copy link
Author

Markz878 commented Oct 23, 2023

This could also lead to developers (at least me) making some mistakes about assuming which branch of the TryTakeFromJson condition is run at which point. In my app I initialize a SignalR connection in the true branch (cause I thought it would always run on the WASM client side), and was confused when the connection was sometimes initialized and sometimes not.

@ghost
Copy link

ghost commented Oct 24, 2023

This issue has been resolved and has not had any activity for 1 day. It will be closed for housekeeping purposes.

See our Issue Management Policies for more information.

@ghost ghost closed this as completed Oct 24, 2023
@dotnet dotnet locked as resolved and limited conversation to collaborators Nov 23, 2023
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-blazor Includes: Blazor, Razor Components ✔️ Resolution: Answered Resolved because the question asked by the original author has been answered. question Status: Resolved
Projects
None yet
Development

No branches or pull requests

2 participants