はじめに
Blazorはコンポーネントベースのフレームワークで、再利用可能なUIコンポーネントを簡単に作成できます。
最近、親子のコンポーネント間でデータを共有する方法を学習したので、まとめておきます。
私は普段、C#でWindowsのデスクトップアプリを開発しています。
Webの技術を体系的に学び、しっかり活用した経験がなく用語の理解も怪しいので、超初歩的な内容になってます。
コンポーネントパラメータ (Component Parameters)
直接親子関係があるコンポーネント同士は、この方法でパラメーターを渡すのが適しています。
例えば以下のように実装します。
// 子コンポーネント (ChildComponent.razor)
<h3>@Message</h3>
@code {
[Parameter]
public string Message { get; set; }
}
// 親コンポーネント (ParentComponent.razor)
<ChildComponent Message="Hello from Parent!" />
[Parameter]
属性を使って子コンポーネント内に公開プロパティを定義し、親コンポーネントでそのプロパティに値を渡します。
すると、子コンポーネントで親から渡ってきた値を使用できます。
カスケードパラメータ (Cascading Parameters)
親から孫以下の子コンポーネントにパラメータを渡す場合、孫以下までバケツリレーのように複数のコンポーネントを経由するのは手間です。
こういった場合にこの方法を使用すると、手間なくパラメーターを渡せます。
例えば以下のように実装します。
// 親コンポーネント (ParentComponent.razor)
<CascadingValue Value="parentValue">
<ChildComponent />
</CascadingValue>
// 子コンポーネント (ChildComponent.razor)
<h3>@ParentValue</h3>
@code {
[CascadingParameter]
public string ParentValue { get; set; }
}
<CascadingValue>
タグを使うことで、指定した値がすべての子孫コンポーネントに自動的に渡されます。受け取る側では [CascadingParameter] 属性を使ってパラメータを取得します。
これにより、深い階層のコンポーネントにもデータを渡せます。
<CascadingValue>
タグで指定したValue
は、型で判定しています。
そのため、その型のパラメータが1つであれば上記実装で問題ないですが、複数ある場合は以下のようにName
を指定する必要があります。
// 親コンポーネント (ParentComponent.razor)
<CascadingValue Name="parent" Value="parentValue">
<ChildComponent />
</CascadingValue>
// 子コンポーネント (ChildComponent.razor)
<h3>@ParentValue</h3>
@code {
[CascadingParameter(Name = "parent")]
public string ParentValue { get; set; }
}
また、以下のように参照型も使用できます。
// 親コンポーネント (ParentComponent.razor)
<CascadingValue Name="UserData" Value="userData">
<CascadingValue Name="AppSettings" Value="appSettings">
<ChildComponent />
</CascadingValue>
</CascadingValue>
@code {
private UserData userData = new UserData { Name = "John Doe", Age = 30 };
private AppSettings appSettings = new AppSettings { Theme = "Dark Mode", Language = "en" };
}
// 子コンポーネント (ChildComponent.razor)
<div>
<h3>Child Component</h3>
<p>User Name: @userData.Name</p>
<p>App Theme: @appSettings.Theme</p>
</div>
@code {
[CascadingParameter(Name = "UserData")]
private UserData userData { get; set; }
[CascadingParameter(Name = "AppSettings")]
private AppSettings appSettings { get; set; }
}
// UserSettings.cs
public class UserData
{
public string Name { get; set; }
public int Age { get; set; }
}
// AppSettings.cs
public class AppSettings
{
public string Theme { get; set; }
public string Language { get; set; }
}
}
さいごに
プロパティアクセスではなく、属性とNameで判別しているのだとは思いますが、
何回見ても、カスケードパラメーターがprivate
でよいのがなんとなく気持ち悪いです。
親→子へのパラメーターの渡し方はこれでカンペキですね!
参考