Twój pierwszy komponent

Komponent jest jednym z podstawowych pojęć w świecie Reacta. Jest bazą, na której buduje się interfejsy użytkownika (UI), przez co idealnie nadaje się na pierwszy temat do nauki!

W tej sekcji dowiesz się

  • Czym jest komponent?
  • Jaką rolę komponenty odgrywają w aplikacji reactowej?
  • Jak napisać swój pierwszy komponent?

Komponenty: cegiełki do budowania UI-a

W świecie aplikacji internetowych HTML pozwala nam na tworzenie dokumentów o bogatej strukturze przy pomocy wbudowanych znaczników, jak <h1> czy <li>:

<article>
<h1>Twój pierwszy komponent</h1>
<ol>
<li>Komponenty: cegiełki do budowania UI</li>
<li>Definiowanie komponentu</li>
<li>Używanie komponentu</li>
</ol>
</article>

Powyższy kod odzwierciedla czytany przez ciebie artykuł <article>, jego nagłówek <h1> i (skrócony) spis treści w postaci listy numerowanej <ol>. Tego typu kod, połączony ze stylami CSS oraz interaktywnością napisaną w JavaScripcie, stoi za każdym paskiem bocznym, awatarem, oknem dialogowym, listą rozwijaną - każdym fragmentem UI-a widocznym w sieci.

React pozwala na połączenie znaczników, CSS-a i JavaScriptu w “komponent”, element wielokrotnego użytku stanowiący część UI-a twojej aplikacji. Powyższy kod, reprezentujący spis treści, mógłby zostać zastąpiony komponentem <TableOfContents />, renderowanym na każdej stronie. Pod spodem nadal byłby to ten sam kod HTML, składający się z <article>, <h1> itd.

Podobnie jak w przypadku znaczników HTML-owych, komponenty można łączyć, zagnieżdżać i zmieniać im kolejność, tworząc w ten sposób całe strony. Dla przykładu, dokumentacja, którą właśnie czytasz, składa się z następujących komponentów:

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

Wraz ze wzrostem złożoności projektu z pewnością zauważysz, że wiele widoków można poskładać z istniejących już komponentów, co znacznie skróci czas pisania kodu. Nasz spis treści mógłby być dodawany do każdej strony jako <TableOfContents />! Co więcej, możesz rozpędzić prace nad aplikacją korzystając z tysięcy komponentów udostępnianych przez reactową społeczność open-source’ową, takich jak Chakra UI czy Material UI.

Definiowanie komponentu

W przeszłości, kiedy programiści tworzyli stronę internetową, składali najpierw HTML, aby zbudować treść, a następnie dokładali kod javascriptowy dodający interakcje. Takie podejście działało, gdy interakcje na stronie były tylko przyjemnym dodatkiem; teraz dla wielu stron jest to mus. React stawia interakcje na pierwszym miejscu, w dalszym ciągu korzystając z tej samej technologii: komponent reactowy jest więc funkcją javascriptową okraszony znacznikami. Oto przykład, jak to może wyglądać w rzeczywistości (poniższy kod można edytować):

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

A oto przepis na stworzenie komponentu:

Krok 1: Wyeksportuj komponent

Prefiks export default należy do standardowej składni JavaScriptu (nie jest specyficzny dla samego Reacta). Pozwala oznaczyć funkcję tak, aby można było ją zaimportować w innych plikach. (Więcej na temat importowania dowiesz się z rozdziału pt. Importowanie i eksportowanie komponentów!)

Krok 2: Zdefiniuj funkcję

Za pomocą function Profile() { } definiujemy funkcję javascriptową o nazwie Profile.

Zwróć uwagę

Komponenty reactowe są zwykłymi funkcjami javascriptowymi, lecz ich nazwy muszą naczynać od wiekiej litery. W przeciwnym razie nie będą działać!

Krok 3: Dodaj kod

Komponent zwraca znacznik <img /> z atrybutami src oraz alt. <img /> jest napisany jak w HTML-u, lecz tak naprawdę pod spodem wykonuje się kod javascriptowy! Ta składnia nosi nazwę JSX i pozwala umieszczać znaczniki w kodzie javascriptowym.

Instrukcje wyjścia (ang. return statements) mogą być napisane w jednej linii, jak w poniższym przykładzie:

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

lecz jeśli znaczniki nie znajdują się w tej samej linii co słowo kluczowe return, musisz otoczyć je parą nawiasów:

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

Zwróć uwagę

Jeśli nie dodasz nawiasów, kod zawarty w kolejnych liniach po return zostanie zignorowany!

Używanie komponentu

Teraz gdy masz już zdefiniowany komponent Profile, możesz zagnieździć go w innych komponentach. Na przykład, możesz wyeksportować komponent Gallery, który wyświetla kilka komponentów Profile:

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

export default function Gallery() {
  return (
    <section>
      <h1>Niesamowici naukowcy</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}

Co widzi przeglądarka

Zauważ różnicę w wielkości liter:

  • <section> zaczyna się od małej litery, dzięki czemu React wie, że mamy na myśli znacznik HTML-owy.
  • <Profile /> zaczyna się od wielkiej litery P, stąd React wie, że mamy na myśli komponent o nazwie Profile.

A sam Profile zawiera jeszcze więcej kodu HTML: <img />. Ostatecznie, to, co trafia do przeglądarki, to:

<section>
<h1>Niesamowici naukowcy</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>

Zagnieżdżanie i rozmieszczanie komponentów

Komponenty są zwykłymi funkcjami javascriptowymi, dzięki czemu możesz mieć kilka komponentów w tym samym pliku. Jest to wygodne, gdy komponenty są małe lub mocno ze sobą powiązane. Jeśli jednak plik zacznie robić się długi i skomplikowany, zawsze możesz przenieść Profile do osobnego pliku. Wkrótce dowiesz się, jak to zrobić, na stronie o importach.

Ponieważ komponenty Profile są renderowane wewnątrz Gallery — nawet kilka razy! — możemy powiedzieć, że Gallery jest komponentem-rodzicem (nadrzędnym), a każdy z Profile jest “dzieckiem” (potomkiem). Na tym właśnie polega magia Reacta: możesz zdefiniować komponent jeden raz, a używać go wielokrotnie w wielu miejscach.

Zwróć uwagę

Komponenty mogą renderować inne komponenty, jednak nigdy nie należy zagnieżdżać ich definicji:

export default function Gallery() {
// 🔴 Nigdy nie definiuj komponentu wewnątrz innego komponentu!
function Profile() {
// ...
}
// ...
}

Powyższy fragment kodu jest bardzo wolny i może powodować błędy. Zamiast tego definiuj każdy komponent na głównym poziomie pliku:

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

// ✅ Deklaruj komponenty na głównym poziomie
function Profile() {
// ...
}

Jeśli komponent potomny potrzebuje jakichś danych od rodzica, przekaż je za pomocą właściwości (ang. props), zamiast zagnieżdżać ich definicje.

Dla dociekliwych

Komponenty od góry do dołu

Twoja aplikacja reactowa zaczyna się w komponencie głównym (ang. root - “korzeń”). Zwykle jest on tworzony automatycznie przy starcie nowego projektu. Na przykład, jeśli używasz CodeSandbox lub frameworka Next.js, komponent główny jest zdefiniowany w pliku pages/index.js. W poprzednich przykładach eksportowaliśmy własne komponenty główne.

Większość aplikacji reactowych używa komponentów “od góry do dołu”. Oznacza to, że nie tylko fragmenty wielokrotnego użytku, jak przyciski, stają się komponentami, lecz także większe kawałki interfejsu, jak paski boczne, listy czy nawet całe strony! Komponenty doskonale sprawdzają się w porządkowaniu kodu UI, nawet jeśli niektórych z nich używamy tylko jeden raz.

Frameworki takie jak Next.js idą o krok dalej. Zamiast tworzyć pusty plik HTML i pozwolić Reactowi “przejąć kontrolę” nad stroną poprzez JavaScript, niektóre frameworki również automatycznie generują kod HTML z komponentów. Umożliwia to wyświetlenie choć części treści strony, podczas gdy kod javascriptowy jest ładowany.

Mimo wszystko wiele stron używa Reacta tylko po to, by dodać do nich “szczyptę interaktywności”. Mają one wiele komponentów głównych zamiast jednego na całą stronę. Świadczy to o tym, że Reacta można używać w takim stopniu, jaki jest aktualnie potrzebny.

Powtórka

Masz za sobą przedsmak tego, co potrafi React! Zróbmy małe podsumowanie.

  • React umożliwia tworzenie komponentów - elementów wielokrotnego użytku stanowiących fragmenty UI-a twojej aplikacji.

  • W aplikacji reactowej każdy kawałek interfejsu użytkownika jest komponentem.

  • Komponenty reactowe są zwykłymi funkcjami javascriptowymi, przy czym:

    1. Ich nazwa musi zaczynać się od wielkiej litery.
    2. Zwracają kod JSX.

Wyzwanie 1 z 4:
Wyeksportuj komponent

Poniższy sandbox nie działa, ponieważ główny komponent nie jest wyeksportowany:

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

Spróbuj naprawić błąd samodzielnie, zanim zajrzyjsz do rozwiązania!