Renderöi ja kommitoi

Ennen kuin komponenttisi näkyvät ruudulla, Reactin näytyy renderöidä ne. Tämän prosessin vaiheiden ymmärtäminen auttaa sinua miettimään miten koodisi suoritetaan ja selittämään sen käyttäytymistä.

Tulet oppimaan

  • Mitä renderöinti tarkoittaa Reactissa
  • Milloin ja miksi React renderöi komponentin
  • Vaaditut vaiheet komponentin näyttämiseksi näytöllä
  • Miksi renderöinti ei aina tuota DOM päivitystä

Kuvittele, että komponenttisi ovat kokkeja keittiössä kasaamassa maukkaita ruokia raaka-aineista. Tässä skenaariossa React on tarjoilija, joka tuo ja vie asiakkaiden tilaukset. Tässä käyttöliittymän pyyntö- ja käyttöprosessissa on kolme vaihetta:

  1. Käynnistää renderöinti (tuoda vierailijan tilaus keittiölle)
  2. Renderöidä komponentti (tilauksen valmistelu keittiössä)
  3. Kommitoida DOM:iin (tilauksen asettaminen pöydälle)
  1. React as a server in a restaurant, fetching orders from the users and delivering them to the Component Kitchen.
    Käynnistää
  2. The Card Chef gives React a fresh Card component.
    Renderöitä
  3. React delivers the Card to the user at their table.
    Kommitoida

Illustrated by Rachel Lee Nabors

1. Vaihe: Käynnistä renderöinti

On kaksi syytä miksi komponentti renderöidään:

  1. Se on komponentin ensimmäinen renderöinti.
  2. Komponentin (tai yhden sen vanhemman) tila on päivittynyt.

Ensimmäinen renderöinti

Kun sovelluksesi käynnistyy, sinun täytyy käynnistää ensimmäinen renderöinti. Ohjelmistokehykset ja hiekkalaatikot joskus piilottavat tämän koodin, mutta se tehdään kutsumalla createRoot funktiota kohde DOM elementillä ja sitten kutsumalla sen render metodia komponenttisi kanssa:

import Image from './Image.js';
import { createRoot } from 'react-dom/client';

const root = createRoot(document.getElementById('root'))
root.render(<Image />);

Kokeile kommentoida root.render() kutsu ja näet komponentin katoavan!

Uudelleenrenderöityy tilan päivittyessä

Kun komponentti on renderöity aluksi, voit käynnistää uusia renderöintejä päivittämällä sen tilaa set funktiolla. Komponentin tilan päivittäminen automaattisesti lisää renderöinnin jonoon. (Voit kuvitella tätä ravintolan vieraana tilaamassa teetä, jälkiruokaa, ja kaikkea muuta alkuperäisen tilauksen jälkeen, janon tai nälän tilasta riippuen.)

  1. React toimii palvelimena ravintolassa, joka tarjoilee käyttäjälle kortin käyttöliittymän, jota edustaa asiakas, jonka pää on kursori. Asiakas ilmaisee haluavansa vaaleanpunaisen kortin, ei mustaa!
    Tilapäivitys...
  2. React palaa komponenttikeittiöön ja kertoo korttikokille, että he tarvitsevat vaaleanpunaisen kortin.
    ...käynnistää...
  3. Korttikokki antaa Reactille vaaleanpunaisen kortin.
    ...renderin!

Illustrated by Rachel Lee Nabors

2. Vaihe: React renderöi komponenttisi

Sen jälkeen kun olet käynnistänyt renderin, React kutsuu komponenttejasi päätelläkseen mitä näyttää ruudulla. “Renderöinti” on React kutsumassa komponenttejasi.

  • Ensimmäisen renderöinnin yhteydessä React kutsuu juurikomponenttiasi.
  • Seuraavissa renderöinneissä React kutsuu komponenttia, jonka tila käynnistää renderöinnin.

Tämä prosessi on rekursiivinen: jos päivitetty komponentti palauttaa jonkin toisen komponentin, React kutsuu sen komponentin seuraavaksi, ja jos se komponentti myös palauttaa jotain, se renderöi sen komponentin seuraavaksi, ja niin edelleen. Tämä prosessi jatkuu kunnes ei ole enempää sisennettyjä komponentteja ja React tietää tarkalleen mitä ruudulla tulisi näkyä.

Seuraavassa esimerkissä, React kutsuu Gallery() ja Image() komponentteja useita kertoja:

export default function Gallery() {
  return (
    <section>
      <h1>Inspiring Sculptures</h1>
      <Image />
      <Image />
      <Image />
    </section>
  );
}

function Image() {
  return (
    <img
      src="https://i.imgur.com/ZF6s192.jpg"
      alt="'Floralis Genérica' by Eduardo Catalano: jättimäinen metallinen kukkaveistos, jossa on heijastavat terälehdet."
    />
  );
}

  • Ensimmäisen renderöinnin aikana React luo DOM nodet <section>, <h1>, ja kolmelle <img> tagille.
  • Uudelleenrenderöinnin aikana, React laskee mitkä niiden propertyistä, jos mitkään, ovat muuttuneet sitten aiemman renderöinnin. Se ei tee näillä tiedoilla mitään ennen seuraavaa commit-vaihetta.

Sudenkuoppa

Renderöinnin on oltava aina puhdas laskelma:

  • Samat sisääntulot, samat ulostulot. Annettaen samat lähtötiedot, puhtaan funktion tulisi aina palauttaa sama lopputulos. (Kun joku tilaa salaatin tomaateilla, sen ei tulisi saada salaatti sipulilla!)
  • Huolehtii omista asioistaan. Se ei muuta yhtään oliota tai muuttujaa joka oli olemassa ennen kuin se renderöitiin. (Toisen tilaus ei pitäisi muuttaa kenenkään muun tilausta.)

Muutoin saatat kohdata hämmentäviä bugeja ja arvaamatonta käyttäytymistä kun koodipohjasi monimutkaisuuden kasvaessa. Kehittäessä “Strict Modessa,” React kutsuu jokaisen komponentin funktiota kahdesti, joka nostaa pintaan epäpuhtaiden funktioiden virheitä.

Syväsukellus

Tehokkuuden optimointi

Päivitetyn komponentin sisäkkäisten komponenttien renderöinti oletuksena ei ole optimaalinen suorituskyvyn kannalta, jos päivittynyt komoponentti on todella korkealla puussa. Jos törmäät ongelmiin suorituskyvyssä, on useita tapoja ratkaista niitä jälkeenpäin. Näitä käydään läpi Suorituskyky osiossa. Älä optimoi ennenaikaisesti!

3. Vaihe: React committaa muutokset DOM:iin

Komponenttisi renderöinnin (kutsumisen) jälkeen React muuttaa DOM:ia.

  • Ensimmäisen renderöinnin jälkeen React käyttää appendChild() DOM API:a asettaakseen luomansa DOM nodet ruudulle.
  • Uudelleenrenderöinteihin React käyttää minimaalisen verran vaadittuja operaatioita (jotka lasketaan renderöinnin aikana!), jotta DOM vastaa viimeisintä renderöintitulosta.

React muuttaa DOM nodeja vain jos renderöintien välissä on eroja. Esimerkiksi, tässä on komponentti, joka uudelleenrenderöityy eri propseilla joka sekunti. Huomaa miten voit lisätä tekstiä <input> kenttään, päivittäen sen value:ta, mutta teksti ei poistu kun komponentti uudelleenrenderöityy:

export default function Clock({time}) {
  return (
    <>
      <h1>{time}</h1>
      <input />
    </>
  );
}

Tämä toimii koska viimeisen vaiheen aikana, React päivittää vain <h1> tagin sisällön time:n arvolla. Se näkee, että <input> JSX:ssä on samassa paikassa kuin viimeksi, joten React ei koske <input> kenttään tai sen value:n!

Epilogi: Selaimen maalaus

Kun renderöinti on valmis ja React on päivittänyt DOM:in, selain uudelleenmaalaa ruudun. Vaikka tämä prosessi tunnetaan “selaimen renderöintinä”, viittaamme siihen “maalaamisena” sekaannuksien välttämiseksi tässä dokumentaatiossa.

After rendering is done and React updated the DOM, the browser will repaint the screen. Although this process is known as “browser rendering”, we’ll refer to it as “painting” to avoid confusion throughout the docs.

A browser painting 'still life with card element'.

Illustrated by Rachel Lee Nabors

Kertaus

  • Mikä tahansa ruudunpäivitys React sovelluksessa tapahtuu kolmessa vaiheessa:
    1. Käynnistys
    2. Renderöinti
    3. Kommitointi
  • Voit käyttää Strict Modea löytääksesi virheitä komponenteistasi
  • React ei koske DOM:iin jos renderöinnin tulos on sama kuin viimeksi