Description
Background and Motivation
This issue addresses the problem with state persistence on root components in Blazor applications. Currently, state persistence fails because the parent component during prerendering is different than the component in interactive mode, causing the loss of key information needed for proper state restoration across render modes.
The core issue is in the GetSerializableKey
method in SupplyParameterFromPersistentComponentStateValueProvider.cs
which produces different values when rendering statically versus when rendering interactively. This inconsistency prevents components from maintaining their state when transitioning between server-side rendering (SSR) and interactive modes (Server or WebAssembly).
Without this fix, developers cannot reliably use persistent component state on root components that cross render mode boundaries, limiting the effectiveness of Blazor's state persistence features in real-world applications.
Proposed API
namespace Microsoft.AspNetCore.Components.Rendering;
public class ComponentState
{
+ protected internal virtual object? GetComponentKey();
}
Usage Examples
The new API is primarily used internally by the framework for state persistence, but it enables consistent behavior across render modes:
// Root component with persistent state that works across render modes
@page "/counter"
@rendermode InteractiveAuto
@key "my-counter"
<h3>Counter</h3>
<p>Current count: @count</p>
<button @onclick="IncrementCount">Increment</button>
@code {
[SupplyParameterFromPersistentComponentState("count")]
private int count;
private void IncrementCount() => count++;
}
// Multiple root components with different keys maintain separate state
<MyComponent @rendermode="InteractiveServer" @key="1" />
<MyComponent @rendermode="InteractiveServer" @key="2" />
The framework now ensures that the same component key is computed during both prerendering and interactive phases, enabling proper state persistence.
Alternative Designs
N/A
Risks
N/A