Kako React djeluje ispod haube

React je vrlo popularna JavaScript knjižnica. S preko 5,5 milijuna preuzimanja tjedno, React uživa veliku popularnost. Ali nema puno React programera koji znaju kako React djeluje ispod haube.

U ovom postu pokušat ću otkriti neke zanimljive stvari o Reactu koje bi vam, kao React programeru, mogle biti fascinantne. Krenimo od početka.

Ali prije nego što započnemo, ako ste React programer, imam nekoliko uzbudljivih vijesti za vas! Nakon što dovršite ovaj članak, moći ćete razviti nešto cool s Reactom i usput osvajati nagrade :)

Što React radi?

U svojoj osnovi, React u osnovi održava stablo za vas. Ovo stablo može izvršiti učinkovite diferencijalne izračune na čvorovima.

Zamislite svoj HTML kôd kao stablo. Zapravo se upravo tako preglednik odnosi prema vašem DOM-u (prikazan HTML u pregledniku). React vam omogućuje učinkovitu rekonstrukciju vašeg DOM-a u JavaScript-u i guranje samo onih promjena u DOM-u koje su se stvarno dogodile.

JSX je sintaktički šećer

Ne postoji ništa poput JSX-a - ni za JavaScript, ni za preglednik. JSX je jednostavno sintaktički šećer za stvaranje vrlo specifičnih JavaScript objekata.

Kad napišete nešto poput:

const tag = 

Hello

ono što zapravo radite je ovo:

const tag = React.createElement("h1", {}, "Hello")

Vidite, kad počnete pisati ugniježđene stvari, ne samo da je ovo teško kodirati, već postaje vrlo nezgodno održavati takvu bazu koda. JSX vam tako pomaže dovesti čistoću HTML-a do snage JavaScript-a.

Ali što React.createElement radi sam? Stvara običan stari JavaScript objekt. Zapravo ga možete ručno nazvati i uvjeriti se sami!

Vidite, imamo ovakav objekt:

{ $$typeof: Symbol(react.element), key: null, props: {children: "Hello"}, ref: null, type: "div" }

A ako počnemo gnijezditi elemente poput ovog:

React.createElement('div', { }, React.createElement('p', {}, 'A p inside a div') ) 

Počeli bismo dobivati ​​ugniježđene objekte:

Dakle, sada znate, nakon što se raščlane svi JSX i riješe svi pozivi React.createElement, slijećemo s jednim gigantskim ugniježđenim objektom kao gore.

Reakcijski renderer

Ako se vratite na točku kada pokrećemo našu aplikaciju, vidjet ćete da ćete u datoteci index.js pronaći sljedeći redak:

// .. prev code ReactDOM.render(, container)

Odozgo, znamo da je po završenom raščlanjivanju ovo samo ogroman objekt React elemenata. Kako je onda React u stanju iz njega stvoriti stvarne div-ove i p tagove? Upoznajte ReactDOM.

ReactDOM zauzvrat, rekurzivno stvara čvorove ovisno o njihovom svojstvu 'type' i napokon ih dodaje DOM-u.

U ovom trenutku mora biti jasno da je zašto je odvajanje React-a od rendera zapravo izvrstan potez! Ono što React radi je jednostavno izraditi stablo korisničkog sučelja koje bi se moglo koristiti ne samo na webu, već i u okruženjima poput mobilnih, s obzirom na to da je dostupan prikazivač koji može komunicirati s glavnim OS-om. Evo, React Native dolazi igrati. Vidite, React Native koristi React knjižnicu, ali ne ReactDOM kao render. Umjesto toga, paket reakcija-izvorni sam je render.

To radimo u reaktivnoj nativnoj aplikaciji za pokretanje aplikacije:

const { AppRegistry } = require('react-native') AppRegistry.registerComponent('app', () => MainComponent)

Izgled! Nema ReactDOM-a. Zašto ne? Budući da nemamo metode poput appendChild, nemamo ni DOM poput okruženja. Umjesto toga, za mobitele trebamo podršku za korisničko sučelje izravno s OS-a. No, React knjižnica to ne mora znati, o tome se brine renderer (React Native).

Reagirajte pomirenje

Kad kažemo da React održava kopiju DOM-a pomoću virtualnog DOM-a u JavaScript-u, a koristi ga za razlikovanje prema svim promjenama i primjenu na stvarni DOM, ne želimo da React izvrši grubu silu. Reagirajte, zapravo radi vrlo lijeno pomirenje. React bi napravio najmanju moguću promjenu, tj. Pokušao bi ponovno koristiti elemente, atribute, pa čak i stilove ako je moguće!

Razmotrite ovaj primjer:

stuff

Recimo da ovaj JSX izraz promijenite u donji koristeći neki uvjet ili neko stanje:

something else

Sada dok se razlikuje, React bi to dobro vidio, img oznaka koristi isto ime klase i na starim i na novim stablima, pa zašto ga mijenjati. I samo bi izmijenio vaš alt atribut i krenuo dalje.

Međutim, postoji kvaka. Budući da ne želimo da React vrši puno izračunavanja na različitim dijelovima, React će pretpostaviti da se, ako se roditelj promijenio, njegovo podstablo koje sadrži definitivno promijenilo. Na primjer:

I did not change

Ako ovaj JSX promijenite u dolje pomoću stanja / stanja:

I did not change

Iako ste mogli vidjeti da ne trebamo ponovno stvarati unutarnju p oznaku, ali React nikako ne može to znati dok prelazite stablo od vrha (osim ako, naravno, ne izvodite teške razlike u stablu, što je mnogo skuplji algoritam od slijedi heuristička O (n) reakcija za razlikovanje). Dakle, React odlučuje uništiti svu djecu (tj. Pozivanje njihovih funkcija čišćenja u useEffect ili componentWillUnmount u komponentama temeljenim na klasi) i ponovno stvoriti djecu od nule.

Ključevi za reakciju

Prilikom dodavanja / uklanjanja elemenata u čvoru, React bi jednostavno prešao preko djece na starom stablu i djece na novom stablu čvora i označio mjesta na kojima treba izvršiti bilo kakvo dodavanje / uklanjanje. Ali to ima nedostatak bez dodatne pomoći programera. Razmotrite ovaj primjer:

  • A
  • B

Uzmite u obzir da je ovo promijenjeno u dolje prema stanju / stanju:

  • Z
  • A
  • B

Sada, kad bi React počeo uspoređivati ​​dva popisa radi razlike, pronašao bi razliku na podređenom čvoru 1, mutirao bi stari A na novi Z, zatim opet na podređenom čvoru 2, promijenio bi ga sa starog B na novi A, a zatim napokon dodati novi B čvor.

Međutim, bolji način bio bi očuvanje postojećih A i B čvorova i samo dodavanje Z čvora. Ali kako bi React znao za to? Pomogli bi tipke React.

Tipke samo pružaju lijep način reagiranja kako bi se znalo koji su se elementi promijenili ili nisu promijenili dok su se razlikovali. Sada bi, umjesto usporedbe cijelog elementa, React usporedio tipke djece kako bi vidio koji element treba dodati / ukloniti. Ispod je učinkovit način izvođenja iste stvari:

  • A
  • B

Ako se ovo promijeni u:

  • Z
  • A
  • B

React bi sada znao da tipke 'A' i 'B' već postoje, pa samo trebamo dodati novi element s tipkom 'Z'.

Jeste li React programer? Pokažite svoje React vještine razvijanjem trominutne interaktivne igre u Reactu i osvojite dukseve, košulje i šalice za kavu ! Sudjelujte u codecompu tako što ćete se ovdje pridružiti codedamn-ovom poslužitelju za razdor

Dakle, ovo su bili neki važni koncepti za koje vjerujem da bi vam bilo jako korisno da kao programeri React počnete razumjeti srž Reacta i kako on zapravo funkcionira. Slobodno proslijedite sve prijedloge ili pitanja koja imate u vezi s istim.

Možete me pratiti na twitteru za još tweetova o JS / kodiranju i sličnih stvari. Mir!