Render i Commit
Pre nego što se vaše komponente prikažu na ekranu, React mora da ih renderuje. Razumevanje koraka u ovom procesu pomoći će vam da razmislite o tome kako se vaš kod izvršava i da objasnite njegovo ponašanje.
Naučićete:
- Šta u React-u znači renderovanje
- Kada i zašto React renderuje komponentu
- Korake potrebne za prikaz komponente na ekranu
- Zašto renderovanje ne ažurira DOM uvek
Zamislite da su vaše komponente kuvari u kuhinji, koji pripremaju ukusna jela od sastojaka. U ovom scenariju, React je konobar koji prenosi porudžbine od gostiju i donosi im njihova jela. Ovaj proces poručivanja i posluživanja UI-a ima tri koraka:
- Pokretanje rendera (prenos porudžbine gosta u kuhinju)
- Renderovanje komponente (priprema porudžbine u kuhinji)
- Commit-ovanje u DOM (postavljanje porudžbine na sto)
Illustrated by Rachel Lee Nabors
Korak 1: Pokrenuti render
Postoje dva razloga da se komponenta renderuje:
- Inicijalni render komponente.
- State se promenio, bilo od komponente ili nekog od njenih roditelja.
Inicijalni render
Kad se aplikacija pokrene, morate započeti inicijalni render. Framework-ovi i sandbox-ovi često skrivaju ovaj kod, ali se on pokreće pozivanjem createRoot
nad željenim DOM čvorom, a nakon toga i pozivanjem render
metode sa vašom komponentom:
import Image from './Image.js'; import { createRoot } from 'react-dom/client'; const root = createRoot(document.getElementById('root')) root.render(<Image />);
Zakomentarišite root.render()
poziv i vidite kako će komponenta nestati!
Ponovni renderi kad se state ažurira
Kada je komponenta inicijalno renderovana, možete pokrenuti naredne rendere ažuriranjem state-a pomoću set
funkcije. Ažuriranjem state-a vaše komponente automatski stavljate render u red čekanja. (Ovo možete zamisliti kao da gost restorana poručuje čaj, dezert i ostale stvari nakon prve porudžbine, u zavisnosti od state-a žeđi i gladi.)
Illustrated by Rachel Lee Nabors
Korak 2: React renderuje vaše komponente
Kada pokrenete render, React poziva vaše komponente da shvati šta da prikaže na ekranu. “Renderovanje” je zapravo React-ovo pozivanje vaših komponenata.
- Pri inicijalnom renderu, React će pozvati root komponentu.
- Za naredne rendere, React će pozvati funkciju komponente čije ažuriranje state-a je pokrenulo render.
Ovaj proces je rekurzivan: ako ažurirana komponenta vrati drugu komponentu, React će renderovati tu drugu komponentu, a ako ta komponenta takođe nešto vrati, renderovaće to nešto sledeće, i tako dalje. Proces će se nastaviti dok god postoje ugnježdene komponente i React zna tačno šta treba biti prikazano na ekranu.
U narednom primeru, React će pozvati Gallery()
i Image()
nekoliko puta:
export default function Gallery() { return ( <section> <h1>Inspirativne skulpture</h1> <Image /> <Image /> <Image /> </section> ); } function Image() { return ( <img src="https://i.imgur.com/ZF6s192.jpg" alt="'Floralis Genérica' napravio Eduardo Catalano: ogromna metalik skulptura cveta sa reflektujućim laticama" /> ); }
- Tokom inicijalnog rendera React će kreirati DOM čvorove za
<section>
,<h1>
i tri<img>
tag-a. - Tokom ponovnog rendera React će izračunati koja od njihovih polja (ili nijedno) su se promenila od prethodnog rendera. Neće uraditi ništa sa tom informacijom do narednog koraka, commit faze.
Deep Dive
Default ponašanje renderovanja svih komponenti ugnježdenih u ažuriranu komponentu nije optimalno za performanse ako je ažurirana komponenta dosta visoko u stablu. Ako naiđete na problem sa performansama, postoji nekoliko opcija da to rešite opisanih u sekciji Performanse. Nemojte optimizovati prerano!
Korak 3: React commit-uje promene na DOM
Nakon renderovanja (pozivanja) vaših komponenata, React će izmeniti DOM.
- Za inicijalni render, React će koristiti
appendChild()
DOM API da postavi sve DOM čvorove koje je kreirao na ekran. - Za ponovne rendere, React će primeniti minimum neophodnih operacija (izračunatih tokom renderovanja!) da bi učinio da se DOM poklapa sa najnovijim rezultatom renderovanja.
React menja DOM čvorove samo ako postoji razlika između rendera. Na primer, ovde je komponenta koja se ponovo renderuje sa drugačijim props-ima koje dobija od roditelja svake sekunde. Primetite da možete dodati tekst u <input>
, menjajući value
, i da taj tekst neće nestati kad se komponenta ponovo renderuje:
export default function Clock({ time }) { return ( <> <h1>{time}</h1> <input /> </> ); }
Ovo radi jer tokom poslednjeg koraka, React jedino ažurira sadržaj <h1>
sa novim time
. On vidi da se <input>
pojavljuje u JSX-u na istom mestu kao prethodni put, pa React ne dira <input>
—niti njegov value
!
Epilog: Browser slikarstvo
Nakon što se renderovanje završi i React ažurira DOM, browser će ponovo oslikati ekran. Iako je ovaj proces poznat kao “browser renderovanje”, mi ćemo ga osloviti sa “slikarstvo” da bi izbegli zabunu kroz dokumentaciju.
Illustrated by Rachel Lee Nabors