(注:昨日誤ってResetボタンのtypeをbuttonに変更してしまいました。本日resetに戻しました。)
現在、Blog、Post、MyButtonの3つのコンポーネントを作成しています。これら3つのコンポーネントのフォントカラーやサイズを統一したい場合、まずMyButtonで[Parameter]属性を持つ変数を定義し、Postから呼び出す際に値を渡し、さらにPostでも変数を定義し、Blogから呼び出す際に値を渡す、という手順を各段階で行う必要があります。
前述の通り、親コンポーネントから子コンポーネントにデータを渡すにはParameterを使用します。Parameterのように、一度にすべての下位コンポーネントに渡す方法はないでしょうか。
そこで登場するのがCascadingValueコンポーネントです。cascadingは「カスケード、噴出」を意味し、「上位から下位へ注入する」と理解できます。フロントエンドで使われるCSSの正式名称もCascading Style Sheet(カスケーディングスタイルシート)です。
まず、BlogBase.razor.csにプロパティColorStyleを追加します(注:筆者が以前ファイル名を誤っていたため、本稿ではBlogBase.razor.csとします)。その値は"color: goldenrod"です。

次に、Blog.razorで<CascadingValue Value="ColorStyle">を使用して<Post>をラップします。

さらに、PostBase.razor.csに同名の変数を定義しますが、こちらには[CascadingParameter]属性を追加します。

そして、適用したい箇所でその変数を指定するだけでOKです。

MyButtonも同様の使い方です。

各コンポーネントで最上位からの変数を受け取るための変数を定義する必要はありますが、[CascadingParameter]により、PostBase.razorで<MyButton>を呼び出す際に値を記入する手間が省けています。
では、2つの値をこのように階層的に渡したい場合はどうすればいいでしょうか。その通り、<CascadingValue>を2重にラップすればOKです。ただし、実際にやってみると、なぜか2つのcolor styleが適用されてしまうことに気づきます。


[管理者注:上下で差異があります。上は管理者のデバッグ結果、下は原文のスクリーンショットです]

これは、<CascadingValue>が変数の型を認識するためです。型が異なれば簡単に適用できますが、同じstringが2つある場合、子要素は最も近い<CascadingValue>のみを適用します。画像の例ではColorStyleが該当します。
この問題を解決するには、Name変数を使用します。これにより、コンポーネント間で<CascadingValue>の名前が認識され、子コンポーネントがそのNameを見つけられない場合は空白を返します。


上記の例から、<CascadingValue>を使用するたびにBlazorが下位コンポーネントに逐次通知していることがわかります。しかし、毎回通知してリソースを消費したくない場合は、IsFixedをtrueに設定することで、Blazorは子コンポーネントに通知しなくなります。

参考:
- Blazor cascading values and parameters
- Blazor multiple cascading parameters
- Blazor cascading values performance
注:本稿のコードは.NET 6 + Visual Studio 2022でリファクタリングしています。原文とリファクタリング後のコードを比較しながら学習することをお勧めします。お読みいただきありがとうございます。原作者をサポートしてください。