Renderowanie i aktualizowanie
Zanim twoje komponenty zostaną wyświetlone na ekranie, muszą zostać wyrenderowane przez Reacta. Zrozumienie tego procesu pomoże ci zrozumieć, jak wykonuje się twój kod i wyjaśni jego zachowanie.
W tej sekcji dowiesz się
- Czym jest renderowanie w Reakcie
- Kiedy i dlaczego React renderuje komponenty
- Kroki związane z wyświetlaniem komponentów na ekranie
- Dlaczego renderowanie nie zawsze powoduje aktualizację drzewa DOM
Wyobraź sobie, że twoje komponenty to kucharze w kuchni, którzy przygotowują smaczne dania z dostępnych składników. W tej sytuacji React jest kelnerem, który przyjmuje zamówienia od klientów i przynosi im zamówione potrawy. Ten proces zgłaszania i obsługi interfejsu użytkownika składa się z trzech kroków:
- Wywołanie (ang. triggering) renderowania (przekazanie zamówienia od gościa do kuchni)
- Renderowanie (ang. rendering) komponentu (przygotowanie zamówienia w kuchni)
- Aktualizowanie (ang. committing) drzewa DOM (umieszczenie zamówienia na stole)
Autor ilustracji Rachel Lee Nabors
Krok 1: Wywołanie renderowania
Istnieją dwa powody, dla których komponent może zostać wyrenderowany:
- To jest początkowe renderowanie komponentu.
- Stan komponentu (lub jednego z jego rodziców) został zaktualizowany.
Początkowe renderowanie
Przy uruchamianiu swojej aplikacji, musisz wywołać początkowe renderowanie. Frameworki i piaskownice czasem ukrywają ten kod, ale jest on wywoływany poprzez wywołanie funkcji createRoot
z docelowym węzłem drzewa DOM, a następnie wywołanie na nim metody render
z twoim komponentem:
import Image from './Image.js'; import { createRoot } from 'react-dom/client'; const root = createRoot(document.getElementById('root')) root.render(<Image />);
Spróbuj zakomentować wywołanie root.render()
i zauważ, że komponent znika!
Przerenderowania po aktualizacji stanu
Po początkowym renderowaniu komponentu, możesz wywołać kolejne przerenderowania poprzez aktualizację jego stanu za pomocą funkcji set
. Aktualizacja stanu komponentu automatycznie dodaje renderowanie do kolejki. (Możesz to sobie wyobrazić jako gościa restauracji zamawiającego herbatę, deser i wszelkiego rodzaju rzeczy już po złożeniu pierwszego zamówienia, w zależności od stanu jego pragnienia lub głodu.)
Autor ilustracji Rachel Lee Nabors
Krok 2: React renderuje twoje komponenty
Po wywołaniu renderowania, React wywołuje twoje komponenty, aby ustalić, co wyświetlić na ekranie. “Renderowanie” oznacza wywołanie twoich komponentów przez Reacta.
- Podczas początkowego renderowania, React wywoła główny komponent.
- Podczas kolejnych renderowań, React wywoła funkcję komponentu, którego aktualizacja stanu wywołała renderowanie.
Proces ten jest rekurencyjny: jeśli zaktualizowany komponent zwraca inny komponent, React następnie wyrenderuje ten komponent, a jeśli ten komponent również coś zwraca, wyrenderuje ten komponent, i tak dalej. Proces będzie kontynuowany, aż nie będzie więcej zagnieżdżonych komponentów i React będzie dokładnie wiedział, co powinno być wyświetlane na ekranie.
W poniższym przykładzie React wywoła Gallery()
i Image()
kilkukrotnie:
export default function Gallery() { return ( <section> <h1>Inspirujące rzeźby</h1> <Image /> <Image /> <Image /> </section> ); } function Image() { return ( <img src="https://i.imgur.com/ZF6s192.jpg" alt="Rzeźba 'Floralis Genérica' wykonana przez Eduardo Catalano: ogromny metalowy kwiat z zwierciadlanymi płatkami" /> ); }
- Podczas początkowego renderowania, React utworzy węzły DOM dla znaczników
<section>
,<h1>
i trzech znaczników<img>
. - Podczas ponownego renderowania, React obliczy, które z ich właściwości, jeśli jakiekolwiek, zostały zmienione od poprzedniego renderowania. Nic nie zrobi z tą informacją aż do następnego kroku, czyli fazy aktualizacji.
Dla dociekliwych
Domyślne zachowanie polegające na renderowaniu wszystkich komponentów zagnieżdżonych w zaktualizowanym komponencie nie jest optymalne pod względem wydajności, jeśli zaktualizowany komponent znajduje się bardzo wysoko w drzewie komponentów. Jeśli napotkasz problemy z wydajnością, istnieje kilka możliwych rozwiązań opisanych w sekcji Wydajność. Nie optymalizuj przedwcześnie!
Krok 3: React aktualizuje zmiany w drzewie DOM
Po wyrenderowaniu (wywołaniu) twoich komponentów, React zmodyfikuje drzewo DOM.
- Podczas początkowego renderowania, React użyje API drzewa DOM o nazwie
appendChild()
, aby umieścić na ekranie wszystkie węzły drzewa DOM, które utworzył. - Podczas przerenderowań, React zastosuje minimum niezbędnych operacji (obliczonych podczas renderowania!), aby dopasować drzewo DOM do wyniku najnowszego renderowania.
React zmienia węzły drzewa DOM tylko wtedy, gdy występuje różnica pomiędzy renderowaniami. Na przykład, oto komponent, który przerenderowuje się co sekundę z różnymi właściwościami przekazywanymi z jego rodzica. Zauważ, że możesz dodać tekst do elementu <input>
, aktualizując jego atrybut value
, ale tekst nie znika, gdy komponent renderuje się ponownie:
export default function Clock({ time }) { return ( <> <h1>{time}</h1> <input /> </> ); }
To działa, ponieważ podczas ostatniego kroku React aktualizuje tylko zawartość znacznika <h1>
nową wartością time
. Widzi on, że znacznik <input>
pojawia się w JSXie w tym samym miejscu co ostatnim razem, więc React nie zmienia tego znacznika ani jego atrybutu value
!
Epilog: Malowanie przez przeglądarkę
Po zakończeniu renderowania i zaktualizowaniu drzewa DOM przez Reacta, przeglądarka przemaluje ekran. Chociaż proces ten jest znany jako “renderowanie przez przeglądarkę”, będziemy się odnosić do niego jako “malowanie”, aby uniknąć nieporozumień w dokumentacji.
Autor ilustracji Rachel Lee Nabors