Skip to content

Commit

Permalink
Cascading values updates (#31488)
Browse files Browse the repository at this point in the history
  • Loading branch information
guardrex authored Jan 18, 2024
1 parent 890e16b commit 5a3d7b2
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 3 deletions.
14 changes: 13 additions & 1 deletion aspnetcore/blazor/components/cascading-values-and-parameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ The following class is used in this section's examples.

:::code language="csharp" source="~/../blazor-samples/8.0/BlazorSample_BlazorWebApp/Dalek.cs":::

The following registrations are made in the app's `Program` file:
The following registrations are made in the app's `Program` file with <xref:Microsoft.Extensions.DependencyInjection.CascadingValueServiceCollectionExtensions.AddCascadingValue%2A>:

* `Dalek` with a property value for `Units` is registered as a fixed cascading value.
* A second `Dalek` registration with a different property value for `Units` is named "`AlphaGroup`".
Expand All @@ -60,6 +60,13 @@ builder.Services.AddCascadingValue(sp =>
});
```

> [!WARNING]
> Registering a component type as a root-level cascading value doesn't register additional services for the type or permit service activation in the component.
>
> Treat required services separately from cascading values, registering them separately from the cascaded type.
>
> Avoid using <xref:Microsoft.Extensions.DependencyInjection.CascadingValueServiceCollectionExtensions.AddCascadingValue%2A> to register a component type as a cascading value. Instead, wrap the `<Router>...</Router>` in the `Routes` component (`Components/Routes.razor`) with the component and adopt global interactive server-side rendering (interactive SSR). For an example, see the [`CascadingValue` component](#cascadingvalue-component) section.
:::moniker-end

## `CascadingValue` component
Expand Down Expand Up @@ -468,3 +475,8 @@ The following `ExampleTabSet` component uses the `TabSet` component, which conta
private bool showThirdTab;
}
```

## Additional resources

* [Generic type support: Explicit generic types based on ancestor components](xref:blazor/components/generic-type-support#explicit-generic-types-based-on-ancestor-components)
* [State management: Factor out the state preservation to a common location](xref:blazor/state-management?pivots=server#factor-out-the-state-preservation-to-a-common-location)
20 changes: 18 additions & 2 deletions aspnetcore/blazor/state-management.md
Original file line number Diff line number Diff line change
Expand Up @@ -493,8 +493,26 @@ else
The `CounterStateProvider` component handles the loading phase by not rendering its child content until state loading is complete.

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

To make the state accessible to all components in an app, wrap the `CounterStateProvider` component around the <xref:Microsoft.AspNetCore.Components.Routing.Router> (`<Router>...</Router>`) in the `Routes` component with global interactive server-side rendering (interactive SSR).

In the `App` component (`Components/App.razor`):

```razor
<Routes @rendermode="InteractiveServer" />
```

In the `Routes` component (`Components/Routes.razor`):

:::moniker-end

:::moniker range="< aspnetcore-8.0"

To use the `CounterStateProvider` component, wrap an instance of the component around any other component that requires access to the counter state. To make the state accessible to all components in an app, wrap the `CounterStateProvider` component around the <xref:Microsoft.AspNetCore.Components.Routing.Router> in the `App` component (`App.razor`):

:::moniker-end

```razor
<CounterStateProvider>
<Router ...>
Expand Down Expand Up @@ -773,8 +791,6 @@ When implementing custom state storage, a useful approach is to adopt [cascading
* To consume state across many components.
* If there's just one top-level state object to persist.

For additional discussion and example approaches, see [Blazor: In-memory state container as cascading parameter (dotnet/AspNetCore.Docs #27296)](https://github.com/dotnet/AspNetCore.Docs/issues/27296).

## Troubleshoot

In a custom state management service, a callback invoked outside of Blazor's synchronization context must wrap the logic of the callback in <xref:Microsoft.AspNetCore.Components.ComponentBase.InvokeAsync%2A?displayProperty=nameWithType> to move it onto the renderer's synchronization context.
Expand Down

0 comments on commit 5a3d7b2

Please sign in to comment.