Week 07 · Day 02 — 常用生命週期鉤子深入

學習目標

  • 深入 ngOnInit / ngOnDestroy / ngOnChanges
  • 在正確時機做正確的事
  • 避免常見錯誤

重點

ngOnInit:初始化 - @Input 已可用的第一次初始

export class ProductComponent implements OnInit {
  @Input() productId!: string;

  ngOnInit(): void {
    // this.productId 此刻已有值,可安全使用
    this.loadProduct(this.productId);
  }
}

ngOnChanges:監看 @Input 變化

export class CounterComponent implements OnChanges {
  @Input() count = 0;
  previous = 0;

  ngOnChanges(changes: SimpleChanges): void {
    if (changes['count']) {
      const cur = changes['count'].currentValue;
      const prev = changes['count'].previousValue;
      console.log(`${prev} -> ${cur}`);
    }
  }
}
- changes['欄位名']previousValue / currentValue

ngOnDestroy:清理

export class TimerComponent implements OnInit, OnDestroy {
  private timer: any;

  ngOnInit(): void {
    this.timer = setInterval(() => console.log('tick'), 1000);
  }

  ngOnDestroy(): void {
    clearInterval(this.timer);   // 一定要清理,避免記憶體洩漏
  }
}

常見錯誤 - ❌ 在 constructor 用 @Input(還沒好) - ❌ 忘记在某個身上建立訂閱但沒清理 - ✅ 初始化用 ngOnInit、清理用 ngOnDestroy

實作

  1. 建立含 ngOnChanges 的元件,觀察 SimpleChanges
  2. 建立 setInterval 並在 ngOnDestroy 清理
  3. 切換路由確認計時器停止

作業

  • ngOnChanges 監看 @Input 變化
  • ngOnDestroy 清理資源
  • 說出為何不能在 constructor 用 @Input