本文へスキップ
BecomeCoder

Angularコース · 第5章 サービスとSignals · レッスン15

Signals ― 新しい状態管理

ブラウザで完結

導入

レッスン11のサービスやレッスン10の配列操作は、値を書き換えたらAngularが自動で画面を更新してくれる「変更検知」という仕組みの上に成り立っていました。近年のAngularは、この仕組みをもっと明示的で軽量にする signal() という新しい状態管理を用意しています。

説明

signal(初期値) で作った値は、関数として呼ぶと現在の値が読めます(count())。.set(値) で置き換え、.update(fn) で今の値をもとに書き換えます。他のsignalから自動で計算される値は computed()、signalが変わるたびに実行したい処理は effect() で書きます。

@Component({
  selector: 'app-root',
  standalone: true,
  template: `
    <h2>Signals で買い物カゴ</h2>
    <p>個数: {{ count() }} 個</p>
    <p>合計金額: {{ total() }} 円</p>
    <button (click)="increment()">+1</button>
    <button (click)="decrement()">-1</button>
    <button (click)="reset()">リセット</button>
  `,
})
class AppComponent {
  price = 100;
  count = signal(0);
  total = computed(() => this.count() * this.price);

  constructor() {
    effect(() => {
      console.log('個数が変わりました:', this.count());
    });
  }

  increment(): void {
    this.count.update((n) => n + 1);
  }
  decrement(): void {
    this.count.update((n) => Math.max(0, n - 1));
  }
  reset(): void {
    this.count.set(0);
  }
}
  • signal(0) … 「監視できる値の箱」を作ります。テンプレートや computedeffect の中で count() と関数として呼ぶと、その時点の値が読めます。
  • computed(() => …) … 他のsignalから自動で計算される値。count が変わるたびに total も自動で再計算されます。
  • effect(() => …) … signalが変わるたびに実行される副作用。ここでは変化のたびに console.log しています(下の「コンソール」欄で確認できます)。
  • .set(値).update(fn) … signalの値を書き換える2つの方法。
  • 普通のプロパティ(count: number = 0 のような書き方)と違い、signalは「誰が読んでいるか」をAngularが正確に把握できるため、より効率よく画面更新できます。

やってみよう

  • price を書き換えて、total が連動して変わることを確認しましょう。
  • effect の中身を「合計金額が◯◯円になりました」のようなログに変えてみましょう。
  • コンソール欄で、ボタンを押すたびに effect が実行されていることを確かめましょう。

実際に動かしてみよう

下のエディタにAngularのコンポーネントを書くと、右側のプレビューにその場で描画されます。本文の例を打ち込んだり書き換えたりして、テンプレート構文やバインディングの動きを確かめながら進めましょう(初回だけ読み込みに少し時間がかかります)。

Angular — ブラウザ内で実行

ブラウザ内でAngular(JIT)を動かす学習用環境(同梱)を読み込みます(初回のみ少し時間がかかります)。
スクロールして表示された時点でも自動で読み込まれます。