この記事の原文は以下よりご確認いただけます。
坂本純一 / 2023年11月27日(月)
Blazor State Management Best Practices | Infragistics Blog
Blazor の「状態管理(State Management)」は、フレームワークを使用して構築する、ユーザー操作を含むアプリケーションの重要な部分です。例えば、社内データにアクセスするために、ユーザーがログインする場合のシナリオを考えてみましょう。
しかし「状態が適切に管理されていない」という場合はどうでしょうか。この場合、ログイン状態がわからずにページを再読み込みするたびに、何度もログインする必要があるでしょう。
このようなアプリケーションをユーザーが使い続ける可能性はとても低いでしょう。これは極端な例ですが、状態管理が疎かになることで「UIの応答性の低下」を招くリスクがあります。ぜひ、「Blazor 状態管理(State Management)」で考慮すべき、ベストプラクティスを学んでいきましょう。
「UI の応答性の低下」が招くユーザーエクスペリエンスの低下を回避するために、開発者は効果的かつ適切な「Blazor の状態管理」を実装する必要があります。Blazor の状態管理を正しく行うことで、アプリケーションのビルドに使用される Blazor コンポーネントが相互に通信し、親コンポーネントから子コンポーネントに特定のデータを効果的に転送できるようになります。
しかし「Blazor の状態管理」とは具体的にはどういうことでしょうか?Blazor WebAssembly アプリと Blazor Server アプリとで違いはあるのでしょうか?このクイックガイドでは、これらの点をより深く掘り下げていきます。Blazor の状態管理が具体的にどのように機能するのかをぜひ学んでください。
あなたが学ぶべきこと:
Blazor アプリでの状態管理の詳細
では、Blazor の状態管理とは何でしょうか。要するに、これはデータを処理するプロセスと、レスポンシブなユーザーインターフェイス(UI)の状態を維持することを指します。これは、いくつかの理由で非常に重要です。
- 「Blazor の状態管理」により、Blazor アプリケーションは接続が切断または失われた場合でも、現在の状態を維持することができます。
- ユーザー固有のデータを記憶できるようにします。
- UI を状態データと同期することできるため、アプリ上のデータ変更を常に反映させることができます。
- Blazor コンポーネント間の通信を容易にします。
- また、クライアント側のリアルタイムの対話性を管理するのに役立ちます。
プロセスがどのようになるかを確認したい場合は、この簡略化された視覚化+説明を見てみましょう。
一般的に、「Blazor の状態管理(State Management)」 は、ユーザー設定やフォーム入力からグローバル設定やリアルタイム更新に至るまで、データの体系的な制御と保存として理解できます。コンポーネントはデータを共有するため、パラメーター、カスケードパラメーター、またはサービスを介してデータを共有しますが、独自のローカル状態を維持することもできます。
適切な状態管理を実行するために、グローバルな状態管理コンテナを実装する必要がある場合があります。共有データを一元管理するための一元化されたリポジトリとして機能すると同時に、一貫したアクセスと更新も保証します。
しかし、状態の更新をトリガーするものは何でしょうか?これには、ユーザー操作、イベント、または外部からの変更が含まれます。状態の更新がトリガーされると、Blazor コンポーネントはそれらをサブスクライブし、変更に従って UI をレンダリングします。
以下は、Blazor の状態管理の使用を検討する必要がある一般的なユースケースです。
- コンポーネント階層内で直接関連していない複数のコンポーネント間でデータ交換と相互作用がある場合。
- アプリケーションのさまざまな部分で共有およびアクセスする必要があるデータがあり、ユーザーの認証ステータス、承認、ロールなどを追跡する必要がある場合。
- ユーザーの操作やデータの変更などに応じて UI を更新する場合。
- 複数のコンポーネントがアクセスする共有アプリケーション設定または構成の場合。
- データが頻繁に変更されない場合に Blazor アプリのパフォーマンスと応答性を向上させるためのデータキャッシュ。
- ページの更新がある場合(ページ/アプリにショッピングカートやデータフォームなどがある場合など)にユーザー固有のデータを保持するため。
- ユーザー固有の設定(表示設定、レイアウトの選択肢など)を保存して、パーソナライズされたUXを作成します。
- リアルタイム更新をクライアントとサーバー間で配布する必要がある場合。
- 各ステップが状態を維持するマルチステップのウィザードスタイルのインターフェイスを作成し、ユーザーが進行状況を維持しながら前後に移動できるようにします。
- また、フィルター、ソート基準、またはデータ・グリッドまたはリストに適用される検索照会を保守する場合にも役立ちます。
もちろん、アプリケーションの特定の目的とロジック、およびさまざまな状態管理手法がそれを最も十分に達成するためにどのように役立つかを常に考慮してください。
Blazor で状態管理を使用する方法
Blazor の仕組みについては過去に概説してきましたが、簡単に要約すると、このフレームワークを使用すると、純粋な「C# スキル」と「.NET」を使用して対話型の Web アプリケーションを構築できます。ここには JavaScript は必要ではありません。
ただし、クライアントとサーバーの相互作用を処理するには 2 つの方法があります。Blazor アプリを構築する 1 つ目の方法は「Blazor Server」を使用する方法であり、もう 1 つは 「Blazor WebAssembly (WASM) 」を使用する方法です。
Blazor Server では、アプリはサーバー上で実行され、すべての UI 更新が SignalR 接続を介してクライアントにフェッチされます。これにより、集中制御によるリアルタイムアプリケーションに適しています。
一方、Blazor WebAssembly は Web ブラウザーで直接実行されるため、クライアント側での完全な実行が可能になります。これは、アプリがオフラインで動作する必要があるシナリオや、クライアント リソースの消費量の増加を処理しながら、サーバーの操作を最小限に抑える必要があるシナリオに最適です。
これらのアーキテクチャの違いは、Blazor Server の状態管理と Blazor WebAssembly の状態管理にも反映されます。これをさらに詳しく見てみましょう。
Blazor Server の状態管理
まず最初に、Blazor Server では「SignalR通信」を使用してリアルタイムの状態を更新できます。ただし、一般的に、Blazor Server の状態管理は、回線単位でのメモリ構造になっていることから、リアルタイム更新のフェッチ検索をした場合に、タイムアウトが問題になる可能性があります。接続ができない状態がごく短時間の場合や、ネットワーク遅延時間が長くない限りは問題ありません。このシナリオでは、Blazor は同じ回線への再接続を試みます。
しかし、それが失敗し、遅延時間が長すぎると、新しい回線が確立され、重要なデータが失われる可能性があります。
Blazor WebAssembly の状態管理
Blazor WebAssembly での状態管理に関しては、状態はユーザーが使用するブラウザーでホストされます。そのため、状態管理がサーバーのメモリに依存しないことから、アプリケーションの整合性は、ネットワークとの遅延や接続の問題の影響を受けません。ただし、ページを更新したり、アプリケーションを再度開いたりすると、通常、状態がリセットされます。
例えば、ローカルストレージを使用してページ間の状態を保持する複数ページのフォームを持つ Blazor アプリがあるとします。これにより、ユーザーは未記入のフォームを送信せずに [戻る] ボタンと [進む] ボタンを持つことができます。長いアンケートフォームのようなものです。
状態管理の例
どちらの場合も、Microsoftが最初に強調したように、状態の永続化の実行について考える必要があります。
"...一般に、ユーザーが既存データを単に読み取るのではなく、活発にデータを作成している場合は、回線間で状態を保持します。
回線間で状態を維持するには、アプリで、サーバーのメモリとは異なる他の保存場所に、データを保持する必要があります。 状態は自動的に保存されません。 ステートフルなデータ保存を実装するアプリを開発するとき、措置を講じる必要があります。
データの保持は、通常、作成するためにユーザーが大きな労力を費やした、価値の高い状態の場合にのみ必要です。"
状態を保持する一般的な場所は次のとおりです。
- サーバー側のストレージ (データベース)
- クライアント側 (ブラウザー)
- URL
- メモリ内状態コンテナーサービス
また、異なるユーザーやデバイス間でのデータ永続性に関しては、サーバー側のストレージに依存することができます。使用可能なオプションは次のとおりです。
- BLOB ストレージ
- キーとバリュー ストレージ
- リレーショナル・データベース
- テーブルストレージ
データが保存されると、ユーザーの状態は保持され、どの回線からでもアクセスできます。
Blazor アプリケーションの状態管理のベスト プラクティス
Blazor の状態管理(State Management)の概要、および、Blazor WebAssembly アプリと Blazor Server アプリでのしくみを明確にした後、Infragistics が強調しておきたいベストプラクティスとアプローチについていくつか説明しましょう。
それぞれのアプローチには異なる目的があることに注意してください。そのため、アプローチの選択と、適切なベストプラクティスを導き出すためには、開発現場のシステム要件、必要な状態管理のスコープ設計、Blazor アプリ内での複雑さなど、あなたのプロジェクトの詳細に常に依存します。
コンポーネントのパラメータまたはカスケード値
Blazor では、パラメーターを使用してコンポーネント間でデータを渡すことができます。コンポーネントは、データを受け入れるパラメータを持つことができます。これらのパラメータは、親コンポーネントによって設定できます。カスケードパラメーターを使用すると、同じデータをコンポーネント階層 (親コンポーネントから子コンポーネントへ) に渡したり、アプリのコンテキスト全体で CascadingValue をラップしたりすることもできます。
いつ使用するのが良いか?
パラメータの使用は、階層構造の親コンポーネントと子コンポーネント間でデータを共有する場合に便利です。
URL とクエリパラメーターへの状態の保存
これは、ユーザーが URL を送信することで、アプリケーションとその状態をユーザー間で共有できるため、非常に重要です (例えば、クエリパラメーターとして埋め込まれたフィルター条件値など)。
いつ使用するのが良いか?
たとえば、ユーザーが保存された URL をクリックして特定のビューまたは構成に直接アクセスできるようにする場合や、パーマリンクを作成する場合などです。
フィールドとプロパティによるコンポーネントの状態の維持
Blazor の最も優れた点の 1 つは、各コンポーネントが独自の状態を維持できるため、フィールドとプロパティを使用してコンポーネント内の状態を簡単に管理できることです。これにより、コンポーネントの状態は、それが定義されている特定のコンポーネントに分離されます。
いつ使用するのが良いか?
これは、他のコンポーネントと共有する必要のないコンポーネント固有のデータがある場合に最適です。
依存性注入の使用とサービスの作成
サービスを作成する場合は、依存関係の挿入を使用して、すべてのコンポーネントでサービスを使用できるようにする必要があります。このアプローチは、複数のコンポーネント間でアクセスできるようにする必要があるデータと状態を共有する場合に便利です。
いつ使用するのが良いか?
これは、アプリケーション全体の状態を管理し、さまざまなコンポーネントにデータを提供し、アプリケーションの状態を一元的に管理する場合に最適です。
サードパーティの状態管理ライブラリからのヘルプの取得
Blazor 開発者は、Fluxor、Blazor-State、Redux ベースのライブラリなどのサードパーティライブラリを使用して、アプリの状態を管理できます。これらは状態管理により構造化された複雑なソリューションを提供しているため便利です。また、Flux アーキテクチャなどの確立されたパターンを実装します。
いつ使用するのが良いか?
大規模で複雑な Blazor アプリケーションの状態管理を整理して合理化する場合に最適です。
まとめ
効果的な状態管理を行うことは、応答性が高く、保守性が高く、ユーザーフレンドリーなBlazor アプリケーションを構築するための中核になる機能です。この記事で説明したベストプラクティスを実装することで、プロジェクトでデータを効率的に処理し、コンポーネントの相互作用をシームレスに同期し、より優れた UX を提供できます。
どの方法を選択するにしても、アプリケーションの状態管理のニーズを常に考慮して、長期的にメリットがあるようにすることを忘れないでください。