reactjs

ReactJS – cykl życia komponentu

Z artykułu dowiesz się:

  1. Czym jest cykl życia komponentu
  2. Po co jest cykl życia komponentu
  3. Jakie etapy życia posiada komponent
  4. Jakie metody posiada React do konkretnych etapów życia komponentu

Czym jest cykl życia komponentu?

Cykl życia odnosi się tylko do komponentów stanowych, dzięki niemu mamy wiele metod, które dają nam dużo możliwości, a także pozwalają optymalizować aplikacje.

Cykl życia komponentu możemy podzielić na 3 etapy

  • Montowanie (Mount)
  • Aktualizowanie (Update)
  • Usuwanie (Unmount)

Każdy z etapów ma inne zdarzenia i jest obsługiwany przez metody, które wywołują się w określonej kolejności.

react-lifecycle

Zrodłó: http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

Jedyną wymaganą metodą jest render(). Cały cykl życia zaczyna się z wywołaniem ReactDOM.redner() głównego komponentu

Lifecycle? A po co nam to?

Dzięki lifecycle będziemy mogli pobierać dane z zewnętrznych źródeł w inny sposób niż zdarzenie. Ważnym zastosowaniem jest tez mozliwosc uzyskania dostępu do wyrenderowanego DOM po zmianach w state/props.

Etap pierwszy – Mounting

Tutaj się wszystko zaczyna, nasz komponent jest tworzony. Pierwszą metodą która jest wywoływana już przy tworzenie instancji klasy to constructor(). Nie jest to stricte związane z cyklem życia, ponieważ jest to właściwość klasy JS, ale na pewno warto o niej pamiętać.

Kolejna metoda czyli componentWillMount() nie będzie za często używana, a na dodatek w 17 wersji Reacta zostanie usunięta. Często błędnie wykorzystywało się ją do wysyłania zapytań do API przed renderowaniem.

Czas na najczęściej używaną i wymaganą metodę render(), zawraca ona całą zawartość komponentu tworzy elementy React (rozpoczyna ich cykl życia) które będą montowane, następnie aktualizuje Virtual DOM. Nie możemy używać tutaj setState() ponieważ stworzy nam to nieskończoną pętle.

Ostatnią metodą etapu montowania jest componentDidMount() podczas jej wykonywania prawdziwy DOM jest już zaktualizowany. Najczęściej będziemy w niej modyfikować nowe elementy DOM lub aktualizować stare, ustawiać Intervale itd. Ale tez jest to idealne miejsce to pobierania danych do komponentu.

class App extends React.Component {
    constructor(props){ // 1
        super(props);
        this.state = {
            number: 100,
        }
    }
    componentWillMount() { // 2
        console.log("Przed montowaniem")
    }
    componentDidMount() { // 4
        console.log("Po montowaniu, DOM już gotowy do pracy")
    }
    render() { // 3
        console.log("Renderowanie") 
        return (
            <section>
                {this.state.number}
            </section>
        )
    }
}

Etap drugi – Updating

Aktualizowanie jest następstwem wywołania metody setState(), w cyklu życia komponentu jest to najczęściej powtarzany etap.

shouldComponentUpdate() jest wywoływane tuz przed render, i w zależności co zwróci (true lub false) pozwala przejść do metody render. Wykorzystuję się ją do optymalizacji, gdy nie chcemy, aby React re-renderował komponent po zmianie state’u/props’u.

componentDidUpdate() jest często używana ponieważ tak samo jak componentDidMount ma dostęp do odświeżonego DOM, najlepsze miejsce na korzystanie z interfejsu DOM.

class App extends React.Component {
    state = {
        number: 1,
    }
    addOne = () =>{
        this.setState({number: this.state.number + 1})
    }
    shouldComponentUpdate() {
        // Po pierwszym kliknieciu metoda render nie zostanie wywowała
        // dopiero po drugim kliknięciu zmiana będzie widoczna na ekranie
        if(this.state.number === 1) return false
        else return true
    }
    componentDidUpdate() {
        // Przyklad korzystania z DOM w React
        document.querySelector('span').style.fontSize = `${16 +this.state.number}px`
    }
    render() {
        return (
            <section>
                <span>{this.state.number}</span><br/>
                <button onClick={this.addOne}>Dodaj 1</button>
            </section>
        )
    }
}

Etap trzeci – Unmouting

Ostatnim etapem życia komponentu jest jego usuwanie, korzystamy tu z jednej metody a konkretnie componentWillUnmount() jest ona bardzo potrzebna, gdyż pozwala wyłączyć eventListenery, itervale itd. przed usunięciem elementów i zostawieniu niepotrzebnych ciągle pracujących funkcji JS

class App extends React.Component {
    state = {
        display: true,
    }
    handleClick = () =>{
        this.setState({
            display: !this.state.display
        })
    }
    render() {
        const {display} = this.state
        return (
            <section>
                {display && <Clock/>} <br/>
                <button onClick={this.handleClick}> {display ? "Ukryj" : "Pokaz" } </button>
            </section>
        )
    }
}

class Clock extends React.Component{
    state = {
        time: new Date().getSeconds()
    }

    // Tworzymy zmienna dla indeksu setIntervala
    interval = ""

    setTime = () => {
        this.setState({
            time: new Date().getSeconds()
        })
    }
    componentDidMount() {
        // Startujemy aktualizowanie sekund po zamontowaniu
        this.interval = setInterval(this.setTime,1000);
    }
    componentWillUnmount() {
        // Gdy zegar ma zniknac usuwany ustawiony Interval
        clearInterval(this.interval)
    }
    render(){
        return(
            <span>{this.state.time}</span>
        )}
    }
}

Podsumowanie

Jeżeli uczysz się Reacta, cykl życia jest czymś niezbędnym podczas pracy z tą biblioteką. Zespół React pracuje ciągle nad tymi metodami na co wskazują zmiana w wersji 17 ( https://medium.com/@valerii.sukhov/react-17-lifecycle-5b68946c813c). Polecam poczytać więcej na ten temat w oficjalnej dokumentacji React https://pl.reactjs.org/docs/state-and-lifecycle.html