Którego hooka cyklu życia Angulara użyć?

Radosław Krajewski • 9 listopada 2026
Diagram przedstawiający cykl życia komponentu Angular, z wyszczególnieniem kluczowych **angular lifecycle hooks** takich jak `ngOnInit`, `ngOnChanges` i `ngOnDestroy`.

Spis treści

Panel szczegółów dostaje nowe id, ale nadal pokazuje poprzedni rekord, bo kod reaguje tylko przy tworzeniu komponentu. Najczęściej trzeba wtedy obsłużyć ngOnChanges, choć właściwy moment zależy od tego, czy problem dotyczy wejścia, widoku, czy sprzątania po komponencie.

Hook dobierz do chwili, w której Angular udostępnia potrzebne dane

  • ngOnChanges reaguje na zmiany wejść i przy pierwszej inicjalizacji działa przed ngOnInit.
  • ngOnInit uruchamia się raz, gdy Angular ustawi wejścia komponentu.
  • ngAfterViewInit pozwala odczytać zapytania do widoku, ale zmiana stanu powiązanego z szablonem może wywołać błąd NG0100.
  • ngOnDestroy, DestroyRef i takeUntilDestroyed pomagają kończyć pracę komponentu i jego subskrypcji.
  • afterNextRender służy do kodu po renderowaniu DOM w przeglądarce; nie uruchamia się podczas renderowania po stronie serwera.

Diagram przedstawiający cykl życia komponentu Angular, z wyróżnionymi angular lifecycle hooks: ngOnChanges, ngOnInit, ngDoCheck, ngAfterContentInit, ngAfterContentChecked, ngAfterViewInit, ngAfterViewChecked, ngOnDestroy.

ngOnChanges wyprzedza ngOnInit i reaguje na kolejne wejścia

Komponent potomny może powstać raz, a dostać kilka różnych wartości wejściowych. Właśnie dlatego ngOnInit nie wystarczy, gdy trzeba ponownie zareagować na zmianę danych przekazanych przez rodzica.

Podczas pierwszego sprawdzenia Angular wywołuje ngOnChanges, jeśli zmieniły się wejścia, a potem ngOnInit. Kolejne zmiany wejść ponownie uruchamiają ngOnChanges. Metoda otrzymuje obiekt SimpleChanges, w którym dla zmienionego pola znajdziesz poprzednią i bieżącą wartość oraz informację, czy to pierwsza zmiana.

export class DetailsComponent implements OnChanges {
  @Input() recordId = '';

  ngOnChanges(changes: SimpleChanges): void {
    const change = changes['recordId'];

    if (change) {
      this.loadRecord(change.currentValue);
    }
  }
}

Jeśli recordId zmienia się po nawigacji między rekordami, pobranie danych w ngOnInit wykonałoby się tylko przy pierwszym utworzeniu komponentu. Obsługa zmiany wejścia trafia do ngOnChanges; konfiguracja potrzebna tylko raz może pozostać w ngOnInit. Dokumentacja Angulara wskazuje też, że przy aliasie wejścia kluczem w SimpleChanges pozostaje nazwa właściwości w klasie.

NG0100 często oznacza zmianę stanu po sprawdzeniu widoku

Odczyt referencji do elementu i zmiana wartości wyświetlanej w szablonie to dwie różne operacje. ngAfterViewInit pozwala odczytać zapytania do widoku po jego inicjalizacji, ale zmiana w tym miejscu wartości powiązanej z szablonem może skończyć się błędem ExpressionChangedAfterItHasBeenCheckedError (NG0100).

Popularna rada, by przenieść problematyczny kod do innego hooka „po widoku”, nie zawsze rozwiązuje przyczynę. W dokumentacji Angulara błąd NG0100 wiąże się ze zmianą wyrażenia po zakończeniu sprawdzania. W trybie deweloperskim framework wykonuje dodatkową kontrolę, która wykrywa niestabilny widok. Jeśli inicjalizujesz stan, zacznij od ngOnInit; jeśli potrzebujesz jedynie odczytać element widoku, użyj ngAfterViewInit bez modyfikowania stanu, od którego zależy bieżący szablon.

Sytuacja Prawdopodobna przyczyna Co zrobić
Widok zmienia się po przypisaniu wartości w ngAfterViewInit Powiązanie szablonu zmieniło się po sprawdzeniu widoku Ustaw początkowy stan wcześniej albo oddziel odczyt referencji od zmiany danych szablonu
Po zmianie parametru rodzica zostaje poprzedni rekord Logika działa tylko w ngOnInit Reaguj na zmienione wejście w ngOnChanges
W konsoli pojawiają się skutki pracy po usunięciu komponentu Subskrypcja lub inny zasób nadal działa Zakończ go przy niszczeniu komponentu, na przykład przez takeUntilDestroyed
Kod dotykający DOM działa w przeglądarce, ale nie przy renderowaniu serwerowym Callback renderowania nie uruchamia się na serwerze Nie zakładaj dostępności DOM w kodzie SSR; przenieś operację do ścieżki wykonywanej w przeglądarce

W tym rozróżnieniu stawiam na moment, w którym dane są rzeczywiście gotowe, zamiast na nazwę hooka, która „brzmi jak właściwa”. To zwykle prowadzi do prostszej naprawy niż wymuszanie kolejnego sprawdzenia widoku.

Do DOM użyj callbacku renderowania, a ciężkie hooki zostaw w spokoju

Metody ngDoCheck, ngAfterContentChecked i ngAfterViewChecked mogą uruchamiać się przy kolejnych przebiegach sprawdzania zmian. Wkładanie do nich kosztownej pracy albo zapisu stanu potrafi obciążyć wiele komponentów naraz, więc sięgam po nie tylko wtedy, gdy standardowe śledzenie zmian nie wystarcza.

Gdy zadanie wymaga pracy z DOM po renderowaniu, nowsze API Angulara udostępnia afterNextRender i afterEveryRender. Rejestruje się je w kontekście wstrzykiwania, na przykład w konstruktorze; callbacki dotyczą renderowania aplikacji, a nie wyłącznie pojedynczej instancji komponentu. Przy afterNextRender praca z DOM może poczekać do następnego renderu, natomiast afterEveryRender uruchamia się po każdym renderze, więc łatwo wykonać niepotrzebnie powtarzalną pracę.

Gdy operacja ma odczytać wymiary, wybieram fazę read; gdy ma zmienić DOM, fazę write. Dokumentacja API Angulara zaleca rozdzielać odczyty i zapisy, gdy to możliwe, bo ich mieszanie może pogorszyć wydajność. Render callbacks nie działają podczas renderowania serwerowego ani prerenderowania, dlatego kod wymagający przeglądarkowego DOM musi uwzględniać ten warunek.

Sprzątanie zacznij tam, gdzie kończy się życie komponentu

Komponent może zniknąć po zmianie trasy albo po wyłączeniu go przez @if. Jeśli uruchomił subskrypcję, timer lub nasłuchiwanie zdarzeń, powinien też zadbać o ich zakończenie. ngOnDestroy jest standardowym miejscem na takie porządki.

W kodzie opartym na RxJS operator takeUntilDestroyed z pakietu @angular/core/rxjs-interop kończy subskrypcję wraz z niszczeniem komponentu lub dyrektywy. Przy innych zasobach można użyć DestroyRef i zarejestrować funkcję porządkową blisko miejsca, w którym zasób powstaje. Takie zestawienie ułatwia ocenę, czy komponent zwalnia wszystko, co sam uruchomił.

Wybór można sprowadzić do prostego warunku: zmienia się wejście - reaguj w ngOnChanges; inicjalizujesz stan raz - użyj ngOnInit; czytasz widok - poczekaj na ngAfterViewInit; dotykasz DOM po renderze - rozważ callback renderowania; kończysz pracę - użyj ngOnDestroy lub DestroyRef.

Dobry hook wynika z tego, co komponent właśnie robi

Przy diagnozie zacznij od rodzaju pracy, nie od pełnej listy metod. Zmiana wejścia, inicjalizacja, dostęp do widoku, manipulacja DOM i sprzątanie dzieją się w różnych momentach, a właściwy hook ogranicza ryzyko starego stanu, błędu NG0100 albo wiszącej subskrypcji.

Jeśli używasz wejść opartych na sygnałach, część reakcji na zmiany można wyrazić przez sygnały obliczane lub efekty; klasyczne hooki nadal przydają się tam, gdzie ich cykl wykonania pasuje do zadania. Najpierw ustal, kiedy potrzebne dane są dostępne i kiedy komponent przestaje istnieć. Dopiero potem wybierz metodę, która w tym momencie daje najczytelniejszy kod.

FAQ - Najczęstsze pytania

Użyj ngOnChanges, gdy komponent ma reagować na kolejne wartości wejścia, na przykład nowy recordId po nawigacji. Hook uruchamia się przy zmianach wejść, także podczas pierwszej inicjalizacji przed ngOnInit, i udostępnia poprzednią oraz bieżącą wartość w SimpleChanges. ngOnInit wykonuje się tylko raz, więc nadaje się do konfiguracji potrzebnej na początku.

Angular zgłasza NG0100, gdy wyrażenie powiązane z szablonem zmieni się po sprawdzeniu widoku. ngAfterViewInit służy do odczytu zapytań do widoku, ale zmienianie w nim stanu wyświetlanego w szablonie może wywołać ten błąd. Początkowy stan ustaw wcześniej, a odczyt referencji do elementu oddziel od zmiany danych szablonu.

Użyj afterNextRender, gdy kod ma wykonać się po następnym renderowaniu DOM w przeglądarce. Callbacki rejestruje się w kontekście wstrzykiwania, na przykład w konstruktorze. Nie uruchamiają się podczas renderowania serwerowego ani prerenderowania, więc kod wymagający przeglądarkowego DOM musi uwzględniać ten warunek.

Do sprzątania przy niszczeniu komponentu służy ngOnDestroy. Subskrypcję RxJS można zakończyć operatorem takeUntilDestroyed z pakietu @angular/core/rxjs-interop. Przy innych zasobach DestroyRef pozwala zarejestrować funkcję porządkową blisko miejsca, w którym zasób powstaje.

Oceń artykuł

Ocena: 5.00 Liczba głosów: 1

Tagi

angular
cykl życia
renderowanie serwerowe
rxjs
Autor Radosław Krajewski
Radosław Krajewski
Nazywam się Radosław Krajewski i od 6 lat zgłębiam tajniki programowania .NET, chmury Azure oraz sztucznej inteligencji. Moja przygoda z tymi technologiami zaczęła się od fascynacji tym, jak złożone problemy można rozwiązywać za pomocą kodu i innowacyjnych narzędzi. Staram się przekazywać tę wiedzę w sposób zrozumiały, dzieląc się swoimi doświadczeniami i spostrzeżeniami na kursdotnet.pl. W moich artykułach skupiam się na praktycznych aspektach, porównuję różne rozwiązania i analizuję najnowsze trendy, aby dostarczyć Wam rzetelne i aktualne informacje, które pomogą Wam rozwijać się w tej dynamicznie zmieniającej się dziedzinie.

Udostępnij artykuł

Napisz komentarz