Skip to content

Commit 5bb40ea

Browse files
authored
Blazor state management updates (#35873)
1 parent b9bca54 commit 5bb40ea

35 files changed

+1545
-1463
lines changed

.openpublishing.redirection.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1623,6 +1623,11 @@
16231623
"source_path": "aspnetcore/whats-new/dotnet-AspNetCore.Docs-mod5.md",
16241624
"redirect_url": "/aspnet/core/release-notes/aspnetcore-10.0",
16251625
"redirect_document_id": false
1626+
},
1627+
{
1628+
"source_path": "aspnetcore/blazor/state-management.md",
1629+
"redirect_url": "/aspnet/core/state-management/",
1630+
"redirect_document_id": false
16261631
}
16271632
]
16281633
}

aspnetcore/blazor/call-web-api.md

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -587,7 +587,7 @@ When using the interactive WebAssembly and Auto render modes, components are pre
587587
* The client version calls the web API with a preconfigured <xref:System.Net.Http.HttpClient>.
588588
* The server version can typically access the server-side resources directly. Injecting an <xref:System.Net.Http.HttpClient> on the server that makes calls back to the server isn't recommended, as the network request is typically unnecessary. Alternatively, the API might be external to the server project, but a service abstraction for the server is required to transform the request in some way, for example to add an access token to a proxied request.
589589
590-
When using the WebAssembly render mode, you also have the option of disabling prerendering, so the components only render from the client. For more information, see <xref:blazor/components/render-modes#prerendering>.
590+
When using the WebAssembly render mode, you also have the option of disabling prerendering, so the components only render from the client. For more information, see <xref:blazor/components/prerender#disable-prerendering>.
591591
592592
Examples ([sample apps](#sample-apps)):
593593
@@ -615,25 +615,29 @@ Use ***either*** of the following approaches:
615615
616616
Example: Todo list web API in the `BlazorWebAppCallWebApi` [sample app](#sample-apps)
617617
618-
* If prerendering isn't required for a WebAssembly component that calls the web API, disable prerendering by following the guidance in <xref:blazor/components/render-modes#prerendering>. If you adopt this approach, you don't need to add <xref:System.Net.Http.HttpClient> services to the main project of the Blazor Web App because the component isn't prerendered on the server.
618+
* If prerendering isn't required for a WebAssembly component that calls the web API, disable prerendering by following the guidance in <xref:blazor/components/prerender#disable-prerendering>. If you adopt this approach, you don't need to add <xref:System.Net.Http.HttpClient> services to the main project of the Blazor Web App because the component isn't prerendered on the server.
619619
620-
For more information, see [Client-side services fail to resolve during prerendering](xref:blazor/components/render-modes#client-side-services-fail-to-resolve-during-prerendering).
620+
For more information, see the [Client-side services fail to resolve during prerendering](xref:blazor/components/prerender#client-side-services-fail-to-resolve-during-prerendering) section of the *Prerendering* article.
621621
622622
## Prerendered data
623623
624624
When prerendering, components render twice: first statically, then interactively. State doesn't automatically flow from the prerendered component to the interactive one. If a component performs asynchronous initialization operations and renders different content for different states during initialization, such as a "Loading..." progress indicator, you may see a flicker when the component renders twice.
625625
626-
<!-- UPDATE 10.0 The status of the enhanced nav fix is scheduled for .NET 10.
626+
You can address this by flowing prerendered state using the Persistent Component State API, which the `BlazorWebAppCallWebApi` and `BlazorWebAppCallWebApi_Weather` [sample apps](#sample-apps) demonstrate. When the component renders interactively, it can render the same way using the same state. However, the API doesn't currently work with enhanced navigation, which you can work around by disabling enhanced navigation on links to the page (`data-enhanced-nav=false`). For more information, see the following resources:
627+
628+
<!-- UPDATE 10.0 The enhanced nav update is in for Preview 7.
629+
The preceding paragraph will be updated/
630+
versioned on the upcoming docs Preview 7 PR.
631+
I'll go ahead and remove the PU issue
632+
cross-link on PR #35873.
633+
627634
Note that the README of the "weather" call web API
628635
sample has a cross-link and remark on this, and the
629636
sample app disabled enhanced nav on the weather
630637
component link. -->
631638
632-
You can address this by flowing prerendered state using the Persistent Component State API, which the `BlazorWebAppCallWebApi` and `BlazorWebAppCallWebApi_Weather` [sample apps](#sample-apps) demonstrate. When the component renders interactively, it can render the same way using the same state. However, the API doesn't currently work with enhanced navigation, which you can work around by disabling enhanced navigation on links to the page (`data-enhanced-nav=false`). For more information, see the following resources:
633-
634-
* <xref:blazor/components/prerender#persist-prerendered-state>
639+
* <xref:blazor/state-management/prerendered-state-persistence>
635640
* <xref:blazor/fundamentals/routing#enhanced-navigation-and-form-handling>
636-
* [Support persistent component state across enhanced page navigations (`dotnet/aspnetcore` #51584)](https://github.com/dotnet/aspnetcore/issues/51584)
637641
638642
:::moniker-end
639643

aspnetcore/blazor/components/cascading-values-and-parameters.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ Add a navigation link to the `DaleksMain` component in `NavMenu.razor`:
290290
</div>
291291
```
292292

293-
Because the <xref:Microsoft.AspNetCore.Components.CascadingValueSource%601>'s type in this example (`NotifyingDalek`) is a class type, you can meet virtually any state management feature specification requirement. However, subscriptions create overhead and reduce performance, so benchmark the performance of this approach in your app and compare it to other [state management approaches](xref:blazor/state-management) before adopting it in a production app with constrained processing and memory resources.
293+
Because the <xref:Microsoft.AspNetCore.Components.CascadingValueSource%601>'s type in this example (`NotifyingDalek`) is a class type, you can meet virtually any state management feature specification requirement. However, subscriptions create overhead and reduce performance, so benchmark the performance of this approach in your app and compare it to other [state management approaches](xref:blazor/state-management/index) before adopting it in a production app with constrained processing and memory resources.
294294

295295
Any change in state (any property value change of the class) causes all subscribed components to rerender, regardless of which part of the state they use. **Avoid creating a single large class representing the entire global application state.** Instead, create granular classes and cascade them separately with specific subscriptions to cascading parameters, ensuring that only components subscribed to a specific portion of the application state are affected by changes.
296296

@@ -517,7 +517,7 @@ Cascading parameters don't pass data across render mode boundaries:
517517

518518
* State crossing the boundary between static and interactive rendering must be serializable. Components are arbitrary objects that reference a vast chain of other objects, including the renderer, the DI container, and every DI service instance. You must explicitly cause state to be serialized from static SSR to make it available in subsequent interactively-rendered components. Two approaches are adopted:
519519
* Via the Blazor framework, parameters passed across a static SSR to interactive rendering boundary are serialized automatically if they're JSON-serializable, or an error is thrown.
520-
* State stored in [`PersistentComponentState`](xref:blazor/components/prerender#persist-prerendered-state) is serialized and recovered automatically if it's JSON-serializable, or an error is thrown.
520+
* State stored in [Persistent Component State](xref:blazor/state-management/prerendered-state-persistence) is serialized and recovered automatically if it's JSON-serializable, or an error is thrown.
521521

522522
Cascading parameters aren't JSON-serializable because the typical usage patterns for cascading parameters are somewhat like DI services. There are often platform-specific variants of cascading parameters, so it would be unhelpful to developers if the framework stopped developers from having server-interactive-specific versions or WebAssembly-specific versions. Also, many cascading parameter values in general aren't serializable, so it would be impractical to update existing apps if you had to stop using all nonserializable cascading parameter values.
523523

@@ -718,4 +718,4 @@ The following `ExampleTabSet` component uses the `TabSet` component, which conta
718718
## Additional resources
719719

720720
* [Generic type support: Explicit generic types based on ancestor components](xref:blazor/components/generic-type-support#explicit-generic-types-based-on-ancestor-components)
721-
* [State management: Factor out state preservation to a common provider](xref:blazor/state-management?pivots=server#factor-out-state-preservation-to-a-common-provider)
721+
* [State management: Protected browser storage: Factor out state preservation to a common provider](xref:blazor/state-management/protected-browser-storage#factor-out-state-preservation-to-a-common-provider)

aspnetcore/blazor/components/data-binding.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1043,7 +1043,7 @@ Prior to the release of .NET 7, two-way binding across components uses `get`/`se
10431043

10441044
:::moniker-end
10451045

1046-
For an alternative approach suited to sharing data in memory and across components that aren't necessarily nested, see <xref:blazor/state-management>.
1046+
For an alternative approach suited to sharing data in memory and across components that aren't necessarily nested, see <xref:blazor/state-management/index>.
10471047

10481048
## Bound field or property expression tree
10491049

aspnetcore/blazor/components/integration-hosted-webassembly.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,6 @@ The persisted prerendered state is transferred to the client, where it's used to
549549

550550
## Additional Blazor WebAssembly resources
551551

552-
* [State management: Handle prerendering](xref:blazor/state-management#handle-prerendering)
553552
* [Prerendering support with assembly lazy loading](xref:blazor/webassembly-lazy-load-assemblies#lazy-load-assemblies-in-a-hosted-blazor-webassembly-solution)
554553
* Razor component lifecycle subjects that pertain to prerendering
555554
* [Component initialization (`OnInitialized{Async}`)](xref:blazor/components/lifecycle#component-initialization-oninitializedasync)
@@ -1064,7 +1063,6 @@ The persisted prerendered state is transferred to the client, where it's used to
10641063

10651064
## Additional Blazor WebAssembly resources
10661065

1067-
* [State management: Handle prerendering](xref:blazor/state-management#handle-prerendering)
10681066
* [Prerendering support with assembly lazy loading](xref:blazor/webassembly-lazy-load-assemblies#lazy-load-assemblies-in-a-hosted-blazor-webassembly-solution)
10691067
* Razor component lifecycle subjects that pertain to prerendering
10701068
* [Component initialization (`OnInitialized{Async}`)](xref:blazor/components/lifecycle#component-initialization-oninitializedasync)
@@ -1322,7 +1320,6 @@ Additional work might be required depending on the static resources that compone
13221320
13231321
## Additional Blazor WebAssembly resources
13241322

1325-
* [State management: Handle prerendering](xref:blazor/state-management#handle-prerendering)
13261323
* [Prerendering support with assembly lazy loading](xref:blazor/webassembly-lazy-load-assemblies#lazy-load-assemblies-in-a-hosted-blazor-webassembly-solution)
13271324
* Razor component lifecycle subjects that pertain to prerendering
13281325
* [Component initialization (`OnInitialized{Async}`)](xref:blazor/components/lifecycle#component-initialization-oninitializedasync)

aspnetcore/blazor/components/integration.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,7 @@ To resolve the problem, use ***either*** of the following approaches:
635635

636636
## Additional Blazor Server resources
637637

638-
* [State management: Handle prerendering](xref:blazor/state-management#handle-prerendering)
638+
* [State management: Protected browser storage: Handle prerendering](xref:blazor/state-management/protected-browser-storage#handle-prerendering)
639639
* Razor component lifecycle subjects that pertain to prerendering
640640
* [Component initialization (`OnInitialized{Async}`)](xref:blazor/components/lifecycle#component-initialization-oninitializedasync)
641641
* [After component render (`OnAfterRender{Async}`)](xref:blazor/components/lifecycle#after-component-render-onafterrenderasync)
@@ -1154,7 +1154,7 @@ To resolve the problem, use ***either*** of the following approaches:
11541154

11551155
## Additional Blazor Server resources
11561156

1157-
* [State management: Handle prerendering](xref:blazor/state-management#handle-prerendering)
1157+
* [State management: Protected browser storage: Handle prerendering](xref:blazor/state-management/protected-browser-storage#handle-prerendering)
11581158
* Razor component lifecycle subjects that pertain to prerendering
11591159
* [Component initialization (`OnInitialized{Async}`)](xref:blazor/components/lifecycle#component-initialization-oninitializedasync)
11601160
* [After component render (`OnAfterRender{Async}`)](xref:blazor/components/lifecycle#after-component-render-onafterrenderasync)
@@ -1586,7 +1586,7 @@ To resolve the problem, use ***either*** of the following approaches:
15861586

15871587
## Additional Blazor Server resources
15881588

1589-
* [State management: Handle prerendering](xref:blazor/state-management#handle-prerendering)
1589+
* [State management: Protected browser storage: Handle prerendering](xref:blazor/state-management/protected-browser-storage#handle-prerendering)
15901590
* Razor component lifecycle subjects that pertain to prerendering
15911591
* [Component initialization (`OnInitialized{Async}`)](xref:blazor/components/lifecycle#component-initialization-oninitializedasync)
15921592
* [After component render (`OnAfterRender{Async}`)](xref:blazor/components/lifecycle#after-component-render-onafterrenderasync)
@@ -2016,7 +2016,7 @@ To resolve the problem, use ***either*** of the following approaches:
20162016

20172017
## Additional Blazor Server resources
20182018

2019-
* [State management: Handle prerendering](xref:blazor/state-management#handle-prerendering)
2019+
* [State management: Protected browser storage: Handle prerendering](xref:blazor/state-management/protected-browser-storage#handle-prerendering)
20202020
* Razor component lifecycle subjects that pertain to prerendering
20212021
* [Component initialization (`OnInitialized{Async}`)](xref:blazor/components/lifecycle#component-initialization-oninitializedasync)
20222022
* [After component render (`OnAfterRender{Async}`)](xref:blazor/components/lifecycle#after-component-render-onafterrenderasync)

aspnetcore/blazor/components/lifecycle.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ Blazor apps that prerender their content on the server call <xref:Microsoft.AspN
206206

207207
:::moniker range=">= aspnetcore-8.0"
208208

209-
To prevent developer code in <xref:Microsoft.AspNetCore.Components.ComponentBase.OnInitializedAsync%2A> from running twice when prerendering, see the [Stateful reconnection after prerendering](#stateful-reconnection-after-prerendering) section. The content in the section focuses on Blazor Web Apps and stateful SignalR *reconnection*. To preserve state during the execution of initialization code while prerendering, see <xref:blazor/components/prerender#persist-prerendered-state>.
209+
To prevent developer code in <xref:Microsoft.AspNetCore.Components.ComponentBase.OnInitializedAsync%2A> from running twice when prerendering, see the [Stateful reconnection after prerendering](#stateful-reconnection-after-prerendering) section. The content in the section focuses on Blazor Web Apps and stateful SignalR *reconnection*. To preserve state during the execution of initialization code while prerendering, see <xref:blazor/state-management/prerendered-state-persistence>.
210210

211211
:::moniker-end
212212

@@ -722,7 +722,7 @@ By combining streaming rendering with persistent component state:
722722
For more information, see the following resources:
723723

724724
* <xref:blazor/components/rendering#streaming-rendering>
725-
* <xref:blazor/components/prerender#persist-prerendered-state>.
725+
* <xref:blazor/state-management/prerendered-state-persistence>.
726726

727727
:::moniker-end
728728

@@ -795,7 +795,7 @@ For more information on the <xref:Microsoft.AspNetCore.Mvc.TagHelpers.ComponentT
795795

796796
:::moniker range=">= aspnetcore-8.0"
797797

798-
The content in this section focuses on Blazor Web Apps and stateful SignalR *reconnection*. To preserve state during the execution of initialization code while prerendering, see <xref:blazor/components/prerender#persist-prerendered-state>.
798+
The content in this section focuses on Blazor Web Apps and stateful SignalR *reconnection*. To preserve state during the execution of initialization code while prerendering, see <xref:blazor/state-management/prerendered-state-persistence>.
799799

800800
:::moniker-end
801801

0 commit comments

Comments
 (0)