0Pricing
Angular Academy · レッスン

Effectのクリーンアップとライフサイクル

Effect内でリソースをクリーンアップします。

「Effectのクリーンアップとライフサイクル」はCoddyKit上の無料Angular Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはAngular Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Angular Academyコースには全4レッスンが含まれています。

クリーンアップが重要な理由

Effectは、タイマー、サブスクリプション、イベントリスナーなどのリソースを開始できます。Effectが再実行されるたびに、古いリソースを先に破棄しなければなりません。そうしないと、タイマーやリスナーがリークします。AngularはこのためのonCleanupフックを提供しています。

onCleanupコールバック

Effect関数はonCleanup関数を受け取ります。これを使って破棄用コールバックを登録すると、Angularは次回の実行前と破棄時にそのコールバックを呼び出します。

import { effect } from '@angular/core';

effect((onCleanup) => {
  const id = setInterval(() => console.log('tick'), 1000);
  onCleanup(() => clearInterval(id));
});

クリーンアップは再実行の前に行われる

依存関係が変化すると、Angularはまず登録済みのクリーンアップを呼び出し、その後でEffect本体を再実行します。これにより、常に1つのリソースだけがアクティブな状態になります。

const delay = signal(1000);

effect((onCleanup) => {
  const id = setInterval(() => console.log('tick'), delay());
  onCleanup(() => clearInterval(id)); // clears old interval first
});

delay.set(500); // old interval cleared, new one started

イベントリスナーのクリーンアップ

Effect内で追加したDOMリスナーは、重複したハンドラーやリークを防ぐため、クリーンアップで削除する必要があります。

effect((onCleanup) => {
  const handler = () => console.log(window.innerWidth);
  window.addEventListener('resize', handler);
  onCleanup(() => window.removeEventListener('resize', handler));
});

サブスクリプションのクリーンアップ

Effect内でObservableを購読する場合は、クリーンアップで購読を解除します。(通常は別のツールを使うことが多いですが、ここではパターンを示しています。)

effect((onCleanup) => {
  const sub = interval$.subscribe(v => console.log(v));
  onCleanup(() => sub.unsubscribe());
});

破棄時のクリーンアップ

Effectを所有するコンポーネントが破棄されると、Angularは最後のクリーンアップを自動的に実行してからEffectを破棄します。タイマーがリークすることはありません。

順序:クリーンアップしてから本体

Effectが初めて実行されるときは、クリーンアップするものがありません。2回目以降は、常にクリーンアップ → 本体の順序で実行されます。

let runs = 0;
effect((onCleanup) => {
  runs++;
  console.log('run', runs, dep());
  onCleanup(() => console.log('cleanup before run', runs + 1));
});

クリーンアップなしで負荷の高い処理を避ける

Effect内で開始する長期間存続するリソースには、必ず対応するクリーンアップを用意してください。よくあるバグはクリーンアップを忘れ、依存関係が変化するたびにインターバルが積み重なることです。

manualCleanupオプション

コンポーネントの外部(たとえば、永続的に存在するルートサービス内)で作成するEffectでは、manualCleanupオプションを使用し、適切なタイミングで自分でref.destroy()を呼び出せます。

const ref = effect(() => {
  console.log(value());
}, { manualCleanup: true });

// You are now responsible for:
// ref.destroy();

代替手段としてのDestroyRef

Effect以外の破棄処理では、DestroyRefをインジェクトし、onDestroyでコールバックを登録できます。Effect内では、実行ごとの破棄処理にonCleanupを使用することを推奨します。

import { inject, DestroyRef } from '@angular/core';

const destroyRef = inject(DestroyRef);
destroyRef.onDestroy(() => console.log('component destroyed'));

仕上げ:すべてを組み合わせる

デバウンスされた同期Effectでは、値が変化するたびに前のタイマーをキャンセルし、新しい保存処理をスケジュールします。

const query = signal('');

effect((onCleanup) => {
  const q = query();
  const id = setTimeout(() => save(q), 300);
  onCleanup(() => clearTimeout(id));
});

理解度チェック

Effectのクリーンアップについて理解度を確認しましょう。

まとめ:Effectのクリーンアップとライフサイクル

Effect内で開始したリソースを破棄するには、onCleanupパラメーターを使用します。

  • クリーンアップは再実行の前と破棄時に行われます。
  • タイマー、リスナー、サブスクリプションは必ずクリーンアップします。
  • 長期間存続するEffectにはmanualCleanupを、一般的な破棄処理にはDestroyRefを使用します。

次は、linkedSignalと応用パターンです。

よくある質問

「Effectのクリーンアップとライフサイクル」レッスンは無料ですか?

はい。「Effectのクリーンアップとライフサイクル」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Angular Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Angular Academyコースには全4レッスンが含まれています。

「Effectのクリーンアップとライフサイクル」で何を学びますか?

Effect内でリソースをクリーンアップします。 ブラウザで直接実行するハンズオンコードでAngular Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Angular Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのAngular Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「Effectのクリーンアップとライフサイクル」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このAngular Academyレッスンでコードを書いて実行できますか?

はい。すべてのAngular Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Computed Signal
  2. Effectsと副作用
  3. Effectのクリーンアップとライフサイクル
  4. linkedSignalと高度なパターン
← Angular Academyに戻る