Vaša prva komponenta

Komponente su jedan od glavnih koncepata u React-u. One predstavljaju osnovu pomoću koje pravite UI, što ih čini savršenim mestom za početak vaše React avanture!

Naučićete:

  • Šta je to komponenta
  • Koju ulogu komponente igraju u React aplikaciji
  • Kako da napišete vašu prvu React komponentu

Komponente: Blokovi za pravljenje UI-a

HTML nam omogućava da na web-u kreiramo bogato struktuirane dokumente pomoću ugrađenog skupa tag-ova poput <h1> ili <li>:

<article>
<h1>Moja prva komponenta</h1>
<ol>
<li>Komponente: Blokovi za pravljenje UI-a</li>
<li>Definisanje komponente</li>
<li>Upotreba komponente</li>
</ol>
</article>

Ovaj markup predstavlja ovaj članak <article>, njegov naslov <h1> i (skraćenu) tabelu sa sadržajem kao ordered list-u <ol>. Markup poput ovog, u kombinaciji sa CSS-om za stilizovanje i JavaScript-om za interaktivnost, stoji iza svakog sidebar-a, avatar-a, modal-a, dropdown-a, odnosno iza svakog dela UI-a kojeg vidite na web-u.

React vam omogućava da kombinujete markup, CSS i JavaScript u custom “komponente”, reusable UI elemente za vašu aplikaciju. Kod za tabelu sadržaja koji ste videli gore može biti pretvoren u <TableOfContents /> komponentu koju možete renderovati na svakoj stranici. Ispod haube, i dalje će se koristiti isti HTML tag-ovi poput <article>, <h1>, itd.

Kao i sa HTML tag-ovima, komponente možete sastavljati, praviti im redosled i ugnježdavati ih kako bi dizajnirali cele stranice. Na primer, stranica za dokumentaciju koju upravo čitate je napravljena pomoću React komponenata:

<PageLayout>
<NavigationHeader>
<SearchBar />
<Link to="/docs">Dokumentacija</Link>
</NavigationHeader>
<Sidebar />
<PageContent>
<TableOfContents />
<DocumentationText />
</PageContent>
</PageLayout>

Kako vaš projekat raste, uvidećete da dobar deo dizajna može biti sastavljen upotrebom komponenata koje ste već napisali. To može ubrzati vaš razvoj. Tabela sadržaja od gore može biti dodata bilo gde pomoću <TableOfContents />! Možete čak i započeti projekat velikom brzinom uz pomoć ogromnog broja komponenata dostupnih u React-ovoj open source zajednici poput Chakra UI i Material UI.

Definisanje komponente

Tradicionalno, developeri su tokom pravljenja web stranica prvo kreirali sadržaj, a nakon toga su ga obogatili interakcijom pomoću JavaScript-a. Ovo je radilo dobro dok je interakcija bila poželjna na web-u. Danas je ona očekivana na većini sajtova i u svim aplikacijama. React stavlja interakciju na prvo mesto, iako još uvek koristi istu tehnologiju: React komponenta je JavaScript funkcija koju možete obogatiti sa markup-om. Ovako to izgleda (možete menjati primer ispod):

export default function Profile() {
  return (
    <img
      src="https://i.imgur.com/MK3eW3Am.jpg"
      alt="Katherine Johnson"
    />
  )
}

A ovako možete napraviti komponentu:

Korak 1: Export-ovati komponentu

export default prefiks je standardna JavaScript sintaksa (nije specifično za React). Omogućava vam da obeležite glavnu funkciju u fajlu kako biste je mogli import-ovati u drugim fajlovima. (Više o import-ovanju u Import-ovanje i export-ovanje komponenata!)

Korak 2: Definisati funkciju

Pomoću function Profile() { } definišete JavaScript funkciju čije je ime Profile.

Pitfall

React komponente su obične JavaScript funkcije, ali njihova imena moraju da počnu sa velikim slovom ili neće raditi!

Korak 3: Dodati markup

Komponenta vraća <img /> tag sa src i alt atributima. <img /> je napisan kao HTML, ali je, ispod haube, zapravo JavaScript! Ova sintaksa se naziva JSX i omogućava vam da ugradite markup unutar JavaScript-a.

Return iskazi mogu biti napisani u jednoj liniji, kao u ovoj komponenti:

return <img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />;

Ako vaš markup nije u istoj liniji kao i ključna reč return, morate koristiti zagrade:

return (
<div>
<img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />
</div>
);

Pitfall

Bez zagrada, sav kod koji je napisan u linijama ispod return-a biće ignorisan!

Upotreba komponente

Kada ste definisali vašu Profile komponentu, možete je ugnjezditi unutar ostalih komponenata. Na primer, možete export-ovati Gallery komponentu koja koristi više Profile komponenata:

function Profile() {
  return (
    <img
      src="https://i.imgur.com/MK3eW3As.jpg"
      alt="Katherine Johnson"
    />
  );
}

export default function Gallery() {
  return (
    <section>
      <h1>Zadivljujući naučnici</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}

Šta pretraživač vidi

Primetite razliku u veličini slova:

  • <section> je napisano malim slovima, pa React zna da se to odnosi na HTML tag.
  • <Profile /> počinje velikim slovom P, pa React zna da želimo koristiti našu komponentu po imenu Profile.

Profile sadrži još više HTML-a: <img />. Na kraju, ovo je ono što pretraživač vidi:

<section>
<h1>Zadivljujući naučnici</h1>
<img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />
<img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />
<img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />
</section>

Ugnježdavanje i organizacija komponenata

Komponente su obične JavaScript funkcije, tako da možete imati više komponenata u jednom fajlu. Ovo je zgodno kada su komponente relativno male ili su usko povezane međusobno. Ako fajl postane prenatrpan, uvek možete pomeriti Profile u poseban fajl. Naučićete kako se to radi ubrzo na stranici o import-ovanju.

Pošto su Profile komponente renderovane unutar Gallery-a (i to više puta), možemo reći da je Gallery roditeljska komponenta koja renderuje svaki Profile kao “dete”. Ovo je deo React-ove magije: komponentu definišete jednom, a onda je koristite koliko god i gde god želite.

Pitfall

Komponente mogu renderovati druge komponente, ali nikad ne smete ugnježdavati njihove definicije:

export default function Gallery() {
// 🔴 Nikada nemojte definisati komponentu unutar druge komponente!
function Profile() {
// ...
}
// ...
}

Snippet iznad je veoma spor i prouzrokuje bug-ove. Umesto toga, definišite svaku komponentu na najvišem nivou unutar fajla:

export default function Gallery() {
// ...
}

// ✅ Definišite komponente na najvišem nivou unutar fajla
function Profile() {
// ...
}

Kada detetu (child) komponenti trebaju podaci od roditelja (parent), prosledite ih preko props-a umesto da ugnježdavate definicije.

Deep Dive

Komponente nemaju granice

Vaša React aplikacija počinje sa “root” komponentom. Obično je ona kreirana kada započnete novi projekat. Na primer, ako koristite CodeSandbox ili Next.js framework, root komponenta je definisana u pages/index.js. U ovim primerima ste export-ovali root komponente.

Većina React aplikacija koristi komponente svuda. To znači da nećete koristiti komponente samo za reusable delove poput dugmića, već i za veće, kao što su sidebar-ovi, liste, pa čak i cele stranice! Komponente su zgodan način za organizaciju UI koda i markup-a, iako su neke se od njih koriste samo na jednom mestu.

React-based framework-ovi odlaze korak dalje. Umesto da koristite prazan HTML fajl i da pustite React-u “da preuzme” upravljanje stranicom uz pomoć JavaScript-a, oni takođe automatski generišu HTML na osnovu vaših React komponenata. Na ovaj način vaša aplikacija može prikazati neki sadržaj pre neko što se JavaScript kod učita.

Međutim, veliki broj sajtova koristi React samo za dodavanje interaktivnosti na postojeće HTML stranice. Oni imaju više root komponenata umesto jedne za čitavu stranicu. Možete koristiti React koliko god mnogo, ili malo, da vam treba.

Recap

Upravo ste dobili prvi utisak o React-u! Hajde da rezimiramo par ključnih stvari.

  • React vam omogućava da kreirate komponente, reusable UI elemente za vašu aplikaciju.

  • U React aplikaciji, svaki deo UI-a je komponenta.

  • React komponente su obične JavaScript funkcije osim što:

    1. Njihova imena počinju sa velikim slovom.
    2. One vraćaju JSX markup.

Izazov 1 od 4:
Export-ovati komponentu

Ovaj sandbox ne radi jer root komponenta export-ovana:

function Profile() {
  return (
    <img
      src="https://i.imgur.com/lICfvbD.jpg"
      alt="Aklilu Lemma"
    />
  );
}

Pokušajte da ga popravite pre nego što pogledate rešenje!