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フィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- Computed Signal
- Effectsと副作用
- Effectのクリーンアップとライフサイクル
- linkedSignalと高度なパターン