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
34.77k stars 9.82k forks source link

"prerender: false" is ignored in child components #55635

Open halter73 opened 1 month ago

halter73 commented 1 month ago

prerender: false in new InteractiveWebAssemblyRenderMode(prerender: false) and its Server/Auto counterparts only seems to have an effect for top-level render modes. If a parent component specifies a render mode, the prerender configuration of all its children are completely ignored.

https://github.com/dotnet/aspnetcore/issues/53462 reported a similar issue where prerender: true is ignored for child components if a parent component specifies prerender: false. This was closed as by design. IIt makes sense for that particular scenario, because if a child component can pre-render, that doesn't necessarily mean it needs to. And there's no way for the Blazor to know what child components exist during prerendering if the parent is not prerendered, so it's not even detectable until later during interactive rendering.

Ignoring prerender: false is worse mostly because it is possible to not prerender these child components during its parent's prerendering pass, so Blazor developers could easily expect this to work. Furthermore, it's likely that a child component that explicitly asks for prerender: false is doing something like JS interop which fails during prerendering.

If we really cannot make this work, it should at least raise an error like we do when a child component tries to specify a rendermode that incompatible with its parent. (e.g. System.NotSupportedException: Cannot create a component of type 'BlazorApp1.Client.Pages.Counter' because its render mode 'Microsoft.AspNetCore.Components.Web.InteractiveWebAssemblyRenderMode' is not supported by interactive server-side rendering.) I'd prefer to make this scenario work though.

https://github.com/halter73/BlazorChildComponentPrerenderFalse/commit/bb6108e1e5bfd212890ac185acb94ee039d84c7d shows the modifications you can make to the dotnet new blazor -int WebAssembly project template to demonstrate the error. It updates the Counter component to include prerender: false and adds if (!OperatingSystem.IsBrowser()) throw ... in OnInitialize. This will not throw if you navigate directly to /counter, but it also adds Counter as a child to CounterParent which allows prerendering. So, if you navigate to /counter-parent, you'll see the exception.

This repro just happens to be based on the WebAssembly project template, but the same problem exists for interactive server and auto rendermodes.

guardrex commented 3 weeks ago

UPDATE (6/18): I'm adding some remarks to the Render Modes article to cover this.