Pisanie kodu w JSX

JSX to rozszerzenie składni JavaScriptu, które pozwala używać znaczników podobnych do tych w HTML-u wewnątrz pliku javascriptowego. Większość deweloperów korzysta z niego ze względu na zwięzłość, mimo że istnieją inne sposoby na tworzenie komponentów.

W tej sekcji dowiesz się

  • Dlaczego React miesza znaczniki z logiką renderowania
  • Czym JSX różni się od HTML-u
  • Jak wyświetlić informacje za pomocą JSX-a

JSX: Wrzucanie znaczników do JavaScriptu

Sieć WWW z grubsza została zbudowana przy pomocy HTML-u, CSS-a i JavaScriptu. Przez wiele lat deweloperzy trzymali treść w HTML-u, wygląd w CSS-ie i logikę w JavaScripcie - często każda z tych rzeczy była w osobnym pliku! Treść była opisywana znacznikami wewnątrz HTML-u, a logika strony była w osobnym skrypcie JavaScriptowym:

Kod HTML z fioletowym tłem i divem o dwóch znacznikach potomnych: p oraz form.
Kod HTML z fioletowym tłem i divem o dwóch znacznikach potomnych: p oraz form.

HTML

Trzy procedury obsługi zdarzeń z żółtym tłem: onSubmit, onLogin i onClick.
Trzy procedury obsługi zdarzeń z żółtym tłem: onSubmit, onLogin i onClick.

JavaScript

Jednak z czasem strony WWW stały się bardziej interaktywne, a logika częściej stanowiła o zawartości. JavaScript stał się odpowiedzialny za HTML! To dlatego w Reakcie logika renderowania i znaczniki żyją w tym samym miejscu - w komponencie!

Komponent reactowy zawierający kod HTML i JavaScript z poprzednich przykładów. Funkcja o nazwie Sidebar wywołuje funkcję isLoggedIn, podświetloną na żółto. Wewnątrz funkcji, podświetlony na fioletowo, jest znacznik p z poprzedniego przykładu, oraz znacznik Form, odnoszący się do komponentu przedstawionego na następnym diagramie.
Komponent reactowy zawierający kod HTML i JavaScript z poprzednich przykładów. Funkcja o nazwie Sidebar wywołuje funkcję isLoggedIn, podświetloną na żółto. Wewnątrz funkcji, podświetlony na fioletowo, jest znacznik p z poprzedniego przykładu, oraz znacznik Form, odnoszący się do komponentu przedstawionego na następnym diagramie.

Sidebar.js React component

Komponent reactowy zawierający kod HTML i JavaScript z poprzednich przykładów. Funkcja Form, podświetlona na żółto, zawiera dwie procedury obsługi zdarzeń: onClick i onSubmit. Pod spodem przedstawiony jest kod HTML, oznaczony kolorem fioletowym. Kod HTML zawiera element formularza z zagnieżdżonym elementem input, gdzie do każdego z nich przekazano właściwość onClick.
Komponent reactowy zawierający kod HTML i JavaScript z poprzednich przykładów. Funkcja Form, podświetlona na żółto, zawiera dwie procedury obsługi zdarzeń: onClick i onSubmit. Pod spodem przedstawiony jest kod HTML, oznaczony kolorem fioletowym. Kod HTML zawiera element formularza z zagnieżdżonym elementem input, gdzie do każdego z nich przekazano właściwość onClick.

Form.js React component

Trzymanie logiki renderowania przycisku razem z jego kodem znaczników daje nam pewność, że będą zsynchronizowane przy każdej edycji. Z drugiej strony, detale, które nie są ze sobą powiązane, jak np. kody przycisku i paska bocznego, są od siebie odseparowane, dzięki czemu bezpieczniej jest modifykować każde z nich.

Każdy komponent reactowy jest funkcją javascriptową, która może zwracać strukturę renderowaną przez Reacta do przeglądarki. Komponenty te używają rozszerzenia składni zwanego JSX, za pomocą którego określają strukturę kodu. JSX wygląda bardzo podobnie do HTML-u, jednak jest nieco bardziej restrykcyjny, a ponadto może wyświetlać dynamiczną zawartość. Najłatwiej będzie to zrozumieć, kiedy przepiszemy fragment kodu HTML-owego na JSX.

Notatka

JSX i React to dwie różne rzeczy. Zwykle używa się ich razem, jednak możesz używać ich niezależnie od siebie. JSX rozszerzeniem składni, podczas gdy React jest biblioteką javascriptową.

Przekształcanie HTML-u w JSX

Załóżmy, że mamy taki (całkowicie poprawny) kod HTML:

<h1>Lista zadań Hedy Lamarr</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
>
<ul>
<li>Wynaleźć nową sygnalizację świetlną
<li>Przećwiczyć scenę do filmu
<li>Usprawnić technologię rozpraszania widma
</ul>

I chcemy wrzucić go do poniższego komponentu:

export default function TodoList() {
return (
// ???
)
}

Jeśli zwyczajnie skopiujesz kod taki, jaki jest, nie zadziała:

export default function TodoList() {
  return (
    // Nie chce działać!
    <h1>Lista zadań Hedy Lamarr</h1>
    <img 
      src="https://i.imgur.com/yXOvdOSs.jpg" 
      alt="Hedy Lamarr" 
      class="photo"
    >
    <ul>
      <li>Wynaleźć nową sygnalizację świetlną
      <li>Przećwiczyć scenę do filmu
      <li>Usprawnić technologię rozpraszania widma
    </ul>

Dzieje się tak, ponieważ składnia JSX jest nieco bardziej restrykcyjna i ma więcej reguł niż HTML! Błędy, które pojawiają się przy powyższym kodzie, powinny naprowadzić cię na to, jak go naprawić. Jeśli nie, czytaj dalej.

Notatka

W większości przypadków błędy wyświetlane przez Reacta naprowadzą cię na źródło problemu. Jeśli coś nie działa, postępuj zgodnie z instrukcjami!

Zasady składni JSX

1. Zwróć pojedynczy element główny

Aby komponent zwrócił kilka elementów, musimy je opakować w pojedynczy komponent główny.

Możesz, na przykład, użyć znacznika <div>:

<div>
<h1>Lista zadań Hedy Lamarr</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
>
<ul>
...
</ul>
</div>

Jeśli nie chcesz wstawiać dodatkowego <div> do struktury, zamiast tego możesz użyć pary <> oraz </>:

<>
<h1>Lista zadań Hedy Lamarr</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
>
<ul>
...
</ul>
</>

Ten pusty znacznik nazywamy fragmentem reactowym. Fragmenty pozwalają grupować rzeczy bez zostawiania śladu w drzewie HTML przesłanym do przeglądarki.

Dla dociekliwych

Dlaczego musimy opakowywać kilka znaczników JSX-owych?

Składnia JSX wygląda jak HTML, ale pod spodem jest transformowana do zwykłych obiektów javascriptowych. Nie można przecież zwrócić w funkcji dwóch obiektów bez uprzedniego opakowania ich w tablicę. Dlatego właśnie nie można zwrócić dwóch znaczników JSX bez opakowywania ich w jeden główny znacznik lub fragment.

2. Zamknij wszystkie znaczniki

JSX wymaga, by wszystkie znaczniki były jawnie zamknięte: samozamykające się znaczniki jak <img> musimy zapisać jako <img />, a znaczniki opakowujące jak <li>pomarańcze musimy zapisać jako <li>pomarańcze</li>.

Tak wyglądałoby zdjęcie Hedy Lamarr i jej lista zadań z domkniętymi znacznikami:

<>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
/>
<ul>
<li>Wynaleźć nową sygnalizację świetlną</li>
<li>Przećwiczyć scenę do filmu</li>
<li>Usprawnić technologię rozpraszania widma</li>
</ul>
</>

3. Wszystko Większość rzeczy musi być zapisana camelCasem!

JSX przekształcany jest w JavaScript, a atrybuty zapisane w JSX-ie stają się kluczami obiektów javascriptowych. W swoich własnych komponentach zwykle będziemy chcieli odczytywać wartości tych atrybutów pod postacią zmiennych. Jednak JavaScript ma pewne ograniczenia co do nazw zmiennych. Na przykład, nazwy nie mogą zawierać myślników ani być słowami zarezerwowanymi, jak class.

To dlatego w Reakcie wiele atrybutów HTML-owych i SVG zapisujemy camelCasem. Dla przykładu, zamiast pisać stroke-width, piszemy strokeWidth. Z uwagi na fakt, że class jest słowem zarezerwowanym, w Reakcie zapisujemy go jako className, idąc w ślady za nomenklaturą odpowiadającej mu właściwości DOM:

<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
className="photo"
/>

Wszystkie te atrybuty znajdziesz w elementach React DOM. Jeśli zdarzy ci się pomylić, nie martw się - React wyświetli w konsoli przeglądarki błąd z instrukcją, jak naprawić problem.

Zwróć uwagę

Ze względów historycznych atrybuty aria-* oraz data-* piszemy tak, jak w HTML-u, czyli z myślnikami.

Wskazówka: Używaj konwertera JSX

Konwertowanie wszystkich tych atrybutów w odpowiedni kod znaczników jest żmudne! Zalecamy korzystanie z konwertera, który pomoże przekształcić istniejący kod HTML i SVG w JSX. Tego typu konwertery są pomocne w praktyce, jednak warto wiedzieć, co tak naprawdę dzieje się pod spodem, aby umieć pisać JSX samodzielnie.

Oto nasz rezultat końcowy:

export default function TodoList() {
  return (
    <>
      <h1>Lista zadań Hedy Lamarr</h1>
      <img 
        src="https://i.imgur.com/yXOvdOSs.jpg" 
        alt="Hedy Lamarr" 
        className="photo" 
      />
      <ul>
        <li>Wynaleźć nową sygnalizację świetlną</li>
        <li>Przećwiczyć scenę do filmu</li>
        <li>Usprawnić technologię rozpraszania widma</li>
      </ul>
    </>
  );
}

Powtórka

Teraz już wiesz, po co istnieje składnia JSX i jak jej używać w komponentach:

  • Komponenty reactowe grupują w sobie logikę renderowania ze strukturą elementów, ponieważ obie rzeczy są ze sobą powiązane.
  • JSX jest podobny do HTML-u, z kilkoma różnicami. Jeśli zajdzie potrzeba, możesz skorzystać z konwertera.
  • Błędy wyświetlane na ekranie czy w konsoli przeglądarki zwykle poprowadzą cię do rozwiązania problemów z kodem.

Wyzwanie 1 z 1:
Przepisz kod HTML na JSX

Pewien kod HTML został wklejony do komponentu, jednak nie jest zgodny ze składnią JSX. Napraw go:

export default function Bio() {
  return (
    <div class="intro">
      <h1>Witaj na mojej stronie!</h1>
    </div>
    <p class="summary">
      Wrzucam na nią swoje przemyślenia.
      <br><br>
      <b>I <i>zdjęcia</b></i> naukowców!
    </p>
  );
}

Od ciebie zależy, czy poprawisz go ręcznie, czy przepuścisz przez konwerter!