dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.2k stars 9.94k forks source link

[Blazor] It's not possible to use JavaScript for state management when using Static Render Mode. #51128

Closed BarkovskiyMaxim closed 11 months ago

BarkovskiyMaxim commented 11 months ago

Is there an existing issue for this?

Describe the bug

I have a WebComponent that manages its state on the client side and changes the value that was initially initialized from the server using Blazor. As a result, everything works fine until we change the routing. For example, if we navigate to Page1 using the NavBar and then click on Page1 again, the page will reset to the state initialized by the server.

The issue is that within blazor.web.js, when obtaining the layout of the page, a step-by-step comparison of content occurs, and changes are applied. In this case, all page states that were achieved using JS will simply revert to their initial state, while the latest state will still exist in the JS code.

Expected Behavior

It would be great to have the ability to understand how a component is currently being rendered and mark components that should not change when the routing changes.

Steps To Reproduce

For reproduce:

Example: script with web component:

class MyWebComponent extends HTMLElement {
    loading = true;
    connectedCallback() {
        // wait for initialization
        setTimeout(() => {
            this.classList.remove('loading');
            this.loading = false;
        }, 2000)
    }
}

customElements.define('my-web-component', MyWebComponent)

page:

@page "/component"

<my-web-component id="component" class="loading">
    ...some dynamic content here
</my-web-component>

<input type="button" onclick="alert(document.getElementById('component').loading)" value="GetState" />

@code {

}

JSStateInStaticMode.zip

Exceptions (if any)

No response

.NET Version

8.0.100-rc.1.23463.5

Anything else?

No response

javiercn commented 11 months ago

@BarkovskiyMaxim thanks for contacting us.

Can you try a nightly build? We did a lot of work in this area and I am almost sure that this is addressed.

To be very clear, the expected behavior here is that persisted component state is only available on the first interactive render when the webassembly/server circuits starts. The state is not updated via enhanced navigations or any other mechanism, and it only works for interactive components (there is no "persisting state" between static server side renders (enhanced or not))

javiercn commented 11 months ago

@BarkovskiyMaxim could you also make the project available as a public GH repo instead?

ghost commented 11 months ago

Thank you for filing this issue. In order for us to investigate this issue, please provide a minimal repro project that illustrates the problem without unnecessary code. Please share with us in a public GitHub repo because we cannot open ZIP attachments, and don't include any confidential content.

smjxpro commented 11 months ago

When using static rendering, to work JavaScript properly you need to disable enhanced navigation:

`

` I believe there was a plan to do this with attributes.
BarkovskiyMaxim commented 11 months ago

@javiercn Thank you for the response! I've prepared a repository with an example. I didn't have a chance to try the nightly build yet, but I will definitely take a look later.

@smjxpro Thank you, this will work! However, I still want to have the ability to work in SPA mode and use JavaScript :)

MackinnonBuck commented 11 months ago

@BarkovskiyMaxim you can now specify a data-permanent attribute on elements whose content you want preserved across enhanced navigations.

For example, you can do something like:

<my-web-component id="component" class="loading" data-permanent>
    ...some dynamic content here
</my-web-component>

Could you try this and see if it resolves the problem you're facing? Thanks!

ghost commented 11 months ago

Hi @BarkovskiyMaxim. We have added the "Needs: Author Feedback" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.

ghost commented 11 months ago

This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 4 days. It will be closed if no further activity occurs within 3 days of this comment. If it is closed, feel free to comment when you are able to provide the additional information and we will re-investigate.

See our Issue Management Policies for more information.