Cykl życia komponentu
Bardzo dokładnie omawiamy cykl życia komponentów na szkoleniach. zapisz się na szkolenie z React.
Każdy komponent ma pewien określony cykl życia. Na odpowiednich etapach wywoływane są też jego metody cyklu życia. Możemy je podzielić ogólnie na dwie grupy:
- z nazwami zaczynającymi się od will— wywoływane zanim się coś wydarzy
- z nazwami zaczynającymi się od did— wywoływane po tym jak coś się zdarzyło
Oto kolejne etapy życia komponentów:
Montowanie
Komponent jest tworzony i dodawany do drzewa Dom.
- constructor(props)— jeśli definiujesz konstruktor to nie zapomnij wywołać w nim- super(props)na samym początku; możesz też tam ustawić- this.state = {…}bez konieczności używania- setState. To będzie początkowy stan aplikacji. Inne operacje (efekty uboczne, subskrypcje) powinny się znaleźć w- componentDidMount
- componentWillMount()— wywoływany tuż przed zamontowaniem komponentu; ta metoda raczej Ci się nie przyda
- render()— funkcja, która powinna zwrócić jeden z możliwych wyników:- element (JSX)
- tablicę elementów (JSX)
- string lub liczbę
- null(nic się nie renderuje)
- boolean (nic się nie renderuje)
- Portal (stworzony przez ReactDOM.createPortal(…))
 
- componentDidMount()— wywoływana po zamontowaniu komponentu; to dobre miejsce na jakiekolwiek funkcje polegające na DOM lub na subskrypcje (nie zapomnij o usunięciu subskrypcji w- componentWillUnmount()!)
Aktualizacja
Update może zostać wywołany gdy zmieniają się props lub state.
- componentWillReceiveProps(nextProps)— wywoływana m.in. gdy zmieniają się propsy (np. gdy element-rodzic je zmienia); warto porównać- this.propsz- nextPropsi sprawdzić czy rzeczywiście coś się zmieniło (bo nie zawsze musi…)
- shouldComponentUpdate(nextProps, nextState)— wywoływana zawsze przed- render(); jeśli z tej funkcji zwrócisz- falseto- render()nie zostanie wykonany, a widok się raczej nie przerenderuje — można to wykorzystać do optymalizowania aplikacji; UWAGA: komponenty-dzieci nadal mogą się przerenderować np. gdy zmieni się ich- state, a w przyszłości React będzie traktował funkcję- shouldComponentUpdate()tylko jako wskazówkę, a nie wyznacznik — wrócę do tego tematu jeszcze
- componentWillUpdate(nextProps, nextState)— wywoływana tuż przed- render()— pamiętaj aby nie modyfikować- statewewnątrz tej funkcji
- render()— j.w.
- componentDidUpdate(prevProps, prevState)— wywoływana od razu po renderze; dobre miejsce na zmiany w DOM (jeśli takowe są potrzebne)
Odmontowanie
Wywoływane gdy komponent jest usuwany z DOM
- componentWillUnmount()— wywoływana przed usunięciem komponentu z DOM; dobre miejsce na „posprzątanie” po sobie — usunięcie timerów, subskrypcji, zmian w DOM itd.
Łapanie błędów
- componentDidCatch(error, info)— wywoływana gdy pojawi się błąd w czasie renderowania, wywoływania metod cyklu życia lub w konstruktorze — zagnieżdżonych komponentów; błędy w samym komponencie nie są tutaj łapane (zostaną złapane w komponencie-rodzicu)
Przykład
Oto prosta aplikacja, która pokazuje ważny przykład używania metod cyklu życia. Są to dwa komponenty, App odpowiada za pokazywanie i ukrywanie (po kliknięciu w przycisk) drugiego komponentu. Drugi komponent to Date, który co sekundę aktualizuje stan i wyświetla aktualną datę i godzinę. Wykorzystane zostały takie lifecycle methods:
- constructor()— ustawianie początkowego stanu
- componentDidMount()— rozpoczęcie odliczania (- setInterval)
- componentWillUnmount()— usunięcie odliczania (- clearInterval)
Warto też zwrócić uwagę na sposób w jaki komponent App renderuje komponent Date w zależności od this.state.dateVisible:
<div>
  {this.state.dateVisible && <DateComponent />}
</div>Jeśli chcesz na bieżąco śledzić kolejne części kursu React.js to koniecznie polub mnie na Facebooku i zapisz się na newsletter.
Ćwiczenie
Ćwiczenie: Stwórz dwa komponenty (rodzic i dziecko). Oto wymagania:
- Rodzic pozwala na ustawienie (- input+- button+- onClick+- setState) jakiejś wartości liczbowej i przekazuje ją do dziecka jako props.
- Dziecko ma początkowo wyświetlać liczbę podaną od rodzica, a dodatkowo ma umożliwiać zwiększanie i zmniejszanie tej liczby (- button+- onClick+- setState).
- W momencie gdy rodzic ustawi liczbę, dziecko powinno zresetować swój stan do podanej liczby (- componentWillReceiveProps).
Aktualizacja 11.02.2019 r.: Przekreśliłem zadania powyżej. Miały one wyłącznie charakter dydaktyczny w celu poznania metody cyklu życia componentWillReceiveProps, ale wiele osób bardzo je sobie zapamiętało i stosowało podobny wzorzec w swoich aplikacjach. Poza tym React oznaczył tę metodę jako przestarzałą i niezalecaną. Zajrzyj do tego wpisu:
https://typeofweb.com/nowe-metody-cyklu-zycia-getderivedstatefromprops-i-getsnapshotbeforeupdate/
Sugerowane tutaj przeze mnie rozwiązanie było błędne. Prawidłowym rozwiązaniem problemu powyżej jest przeniesienie stanu dziecka wyżej — do rodzica (tzw. lifting state up). W ten sposób rodzic kontroluje stan obu inputów, a dziecko informuje go o zmianach, które chce wprowadzić. Dzięki temu unika się kilku częstych problemów: z rerenderem (który mógłby prowadzić do skasowania się wartości z inputów), z koniecznością wykrywania zmian (przez niezalecany componentWillReceiveProps), czy choćby z niejasnym przepływem danych (dane do dziecka od rodzica spływają w dół, ale tylko czasem… a dziecko nigdy nie informuje rodzica o zmianach — to niedobrze!). Oto zaktualizowana treść ćwiczenia:
Zaktualizowane ćwiczenie
Ćwiczenie: Stwórz dwa komponenty (rodzic i dziecko). Oto wymagania:
- Rodzic pozwala na ustawienie w inpucie jakiejś wartości liczbowej i przekazuje ją do dziecka.
- Dziecko ma początkowo wyświetlać liczbę podaną od rodzica, a dodatkowo ma umożliwiać zwiększanie i zmniejszanie tej liczby.
- W momencie, gdy rodzic ustawi liczbę, dziecko powinno zresetować swój stan do podanej liczby.
- Podpowiedź: Zastosuj tutaj lifting state up i stan obu komponentów trzymaj w rodzicu.
Napisz w komentarzu czy się udało. A jeśli masz jakieś wątpliwości albo nawet nie wiesz jak zacząć — odezwij się! Pomogę!
