← Angular コース
82. 状態の置き場所 — コンポーネント・サービス・URL
状態には置き場所が3つあります。その画面の中だけで使う状態(モーダルの開閉など)はコンポーネントの signal に。複数の画面で共有する状態(ログインユーザー、カートの中身など)はサービスの signal、いわゆるストアに。そして検索条件やページ番号のように「URLを共有したら再現されてほしい状態」は、URLのクエリパラメータに置きます。
実務では「この状態は誰が使うか」を先に考えると置き場所が決まります。1画面だけならコンポーネントで十分、画面をまたぐならサービス、リロードや共有で残したいならURL。この判断を最初にしておくと、後から「別の画面でもカートの件数を出したい」となっても改修が小さく済みます。
落とし穴は両極端です。「とりあえず全部サービス」にすると、1画面限りの状態までアプリ全体に残り続けて掃除に苦労します。逆に「全部コンポーネント」だと、共有したくなった途端に Input のバケツリレーが始まります。まずコンポーネントに置き、共有が必要になったらサービスへ昇格、が現実的な進め方です。
サンプルコード(フレームワーク環境が必要なため表示のみ)
// ── 状態の3つの置き場所 ──
//
// ① その画面だけの状態 → コンポーネントの signal
// 例: モーダルの開閉、タブの選択、入力途中の値
// isOpen = signal(false);
//
// ② 複数画面で共有する状態 → サービスの signal(ストア)
// 例: ログインユーザー、カートの中身、通知の一覧
// @Injectable({ providedIn: 'root' }) のサービスに持たせる
//
// ③ URLに置くべき状態 → クエリパラメータやパス
// 例: 検索キーワード、ページ番号、並び順
// /products?keyword=apple&page=2
// → URLを共有・リロードしても同じ画面が再現される
//
// 迷ったら「この状態は誰が使うか」から逆算する
サンプルコードで身につける(5本) →
学んだ概念を、素朴な例から実務寄りの例まで5つの具体例で確認します。
公式ドキュメントで詳しく ↗