JSX: rozszerzenie JavaScript i przykłady użycia

Autor: IT Sectr Opublikowano: 2026-07-03 Czas czytania: 10 min

JSX — to rozszerzenie składni JavaScript wzorowane na XML, opracowane przez zespół React do deklaratywnego opisywania interfejsów użytkownika. W przeciwieństwie do silników szablonów, JSX jest kompilowany do zwykłych wywołań funkcji JavaScript, co daje pełną moc języka wewnątrz znaczników. Według React, 2024, JSX jest obsługiwany we wszystkich nowoczesnych frameworkach i bibliotekach React.

Najważniejsze

  • JSX — lukier składniowy nad React.createElement, umożliwiający pisanie znaczników HTML-podobnych w JavaScript.
  • Wyrażenia w JSX osadza się za pomocą nawiasów klamrowych — można używać dowolnych wyrażeń JS.
  • Atrybuty w JSX zapisuje się w camelCase (className, onClick, tabIndex), a nie w kebab-case.
  • Transpilacja JSX do JS jest wykonywana przez Babel, TypeScript lub esbuild przed wykonaniem w przeglądarce.
  • Ochrona XSS jest wbudowana — React eskejpuje wszystkie wartości przed renderowaniem, zapobiegając iniekcjom.

Co to jest JSX?

JSX (JavaScript XML) — rozszerzenie składni JavaScript, po raz pierwszy przedstawione w React w 2013 roku. Pozwala programistom opisywać strukturę interfejsu użytkownika w stylu deklaratywnym, łącząc znaczniki i logikę w jednym pliku.

Przed pojawieniem się JSX programiści używali szablonów tekstowych (Mustache, Handlebars) lub ręcznie tworzyli elementy DOM przez document.createElement. Oba podejścia miały wady: szablony tekstowe nie były sprawdzane pod kątem typów, a ręczne tworzenie DOM było uciążliwe i podatne na błędy.

React wybrał inną ścieżkę — osadzenie znaczników bezpośrednio w kodzie. Ta decyzja wywołała dyskusje w społeczności, ale z czasem stała się standardem. Dziś JSX jest używany nie tylko w React, ale także w SolidJS, Preact, Qwik, a nawet w Vue poprzez wtyczki.

Podstawowa składnia JSX

Element JSX wygląda jak znacznik HTML, ale jest osadzony bezpośrednio w JavaScript. Każdy element jest transpilowany do wywołania React.createElement z trzema argumentami: typem elementu, obiektem propsów i elementami potomnymi. Jeden główny element — obowiązkowa zasada: wyrażenie JSX musi zwracać jeden element nadrzędny lub fragment.

js
import React from 'react';

// Podstawowy JSX - pojedynczy element główny
const element = (
  <div className="app">
    <h1>Hello, World!</h1>
    <p>Welcome to React</p>
  </div>
);

Fragmenty do grupowania

Gdy nie jest potrzebny dodatkowy węzeł DOM, użyj React.Fragment lub krótkiej składni <></>. Fragmenty nie tworzą rzeczywistego elementu DOM, a jedynie grupują węzły potomne. Jest to szczególnie przydatne w tabelach i listach, gdzie dodatkowy opakowujący element zakłóciłby strukturę HTML.

js
function Columns() {
  return (
    <>
      <td>First</td>
      <td>Second</td>
    </>
  );
}

Wyrażenia i zmienne w JSX

Dowolne wyrażenie JavaScript osadza się w JSX za pomocą nawiasów klamrowych { }. Wewnątrz można używać zmiennych, wywołań funkcji, operatorów trójargumentowych i metod tablic. Renderowanie warunkowe wykonuje się za pomocą operatora trójargumentowego lub logicznego AND.

js
function Greeting({ name, isLoggedIn }) {
  const items = ['Red', 'Green', 'Blue'];

  return (
    <div>
      {/* Expression with variable */}
      <h1>Hello, {name}</h1>

      {/* Conditional rendering */}
      {isLoggedIn ?
        <p>Welcome back!</p :
        <button>Login</button>
      }

      {/* Render array */}
      <ul>
        {items.map(item =>
          <li key={item}>{item}</li>
        )}
      </ul>
    </div>
  );
}

Kluczowym ograniczeniem jest to, że wewnątrz nawiasów klamrowych można używać tylko wyrażeń, a nie instrukcji. Nie można używać if/else, for, switch — tylko operator trójargumentowy, operatory logiczne i metody tablic. Wywołania funkcji są dozwolone, w tym funkcji strzałkowych.

Różnice między JSX a HTML

JSX wizualnie przypomina HTML, ale ma zasadnicze różnice. Atrybuty zapisuje się w camelCase — className zamiast class, onClick zamiast onclick, tabIndex zamiast tabindex. Wynika to z faktu, że JSX jest transpilowany do JavaScript, gdzie myślnik w nazwie właściwości jest niedozwolony.

HTMLJSXPrzyczyna
class="wrapper"className="wrapper"class — słowo zastrzeżone w JS
onclick="handle()"onClick={handle}camelCase dla właściwości JS
style="color: red"style={{ color: 'red' }}Obiekt stylów zamiast tekstu
<input disabled><input disabled={true}>Jawne określenie atrybutów boolowskich

Kolejną ważną różnicą są znaczniki samozamykające. W HTML niektóre znaczniki (br, hr, input) mogą pozostać niezamknięte. W JSX wszystkie znaczniki samozamykające muszą mieć ukośnik zamykający: <br />, <input />. Nazwy atrybutów SVG również są konwertowane na camelCase: strokeWidth, fillOpacity.

Jak JSX jest transpilowany do JavaScript

Przeglądarki nie rozumieją JSX bezpośrednio. Przed wykonaniem kod JSX przechodzi przez transpilator — Babel, TypeScript lub esbuild. Każdy element JSX jest zamieniany na wywołanie createElement lub jsx/runtime.

Transformacja przez Babel

js
// Oryginalny JSX
const element = <h1 className="title">Hello</h1>;

// Po transpilacji
const element = React.createElement(
  'h1',
  { className: 'title' },
  'Hello'
);

Od React 17 pojawiła się nowa transformacja JSX, która nie wymaga importowania React. Automatyczny import jsx-runtime pozwala pisać komponenty bez import React from 'react'. Babel i TypeScript obsługują tę transformację poprzez ustawienie {"runtime": "automatic"}.

JSX poza React: Solid, Preact, Vue

Choć JSX kojarzy się z React, inne frameworki również go używają. SolidJS używa JSX z kompilacją do rzeczywistych węzłów DOM, bez Virtual DOM. Preact — lekka alternatywa dla React z pełną obsługą JSX. Vue obsługuje JSX przez @vue/babel-plugin-jsx, choć jego głównym szablonem jest template.

Kluczowa różnica to semantyka wyrażeń. W React wyrażenia JSX są wykonywane przy każdym renderowaniu. W SolidJS JSX jest kompilowany raz, a aktualizacje są śledzone przez sygnały. Wpływa to na wydajność: SolidJS nie wymaga Virtual DOM i reconciliacji, więc renderowanie JSX jest szybsze.

W TypeScript JSX jest obsługiwany na poziomie języka. Pliki z rozszerzeniem .tsx automatycznie obsługują składnię JSX. Typowanie propsów — jedna z głównych zalet TypeScript + JSX: IDE podpowiada oczekiwane atrybuty, typy callbacków i wymagane propsy.

Najlepsze praktyki pracy z JSX

Pisz kod JSX łatwy do czytania i utrzymania. Wydzielaj złożone wyrażenia do osobnych zmiennych lub funkcji — poprawia to czytelność i pozwala testować logikę oddzielnie od znaczników. Używaj fragmentów zamiast zbędnych opakowań div.

Zasada wcięć — przestrzegaj wcięć dla zagnieżdżonych elementów. Każdy poziom zagnieżdżenia to jeden poziom wcięcia. Znacznik zamykający powinien być na poziomie otwierającego. W przypadku długich atrybutów używaj łamania wierszy.

Unikaj funkcji strzałkowych inline w propsach, jeśli są tworzone przy każdym renderowaniu. W takich przypadkach opakuj callback w useCallback lub wynieś funkcję poza komponent. Dziel złożone komponenty na mniejsze — każdy komponent powinien odpowiadać za jedną logiczną jednostkę interfejsu.

Często zadawane pytania

Czy można używać JSX bez React?

Tak, przez wtyczkę Babel @babel/plugin-transform-react-jsx można skonfigurować JSX dla dowolnej biblioteki. SolidJS, Preact, Nerv i inne frameworki używają JSX z własnym środowiskiem wykonawczym. Dla pełnej niezależności można ustawić pragma na własną funkcję.

Dlaczego w JSX nie można używać class zamiast className?

class jest słowem zastrzeżonym w JavaScript. JSX jest transpilowany do createElement, gdzie drugim argumentem przekazywany jest obiekt propsów. Właściwość class koliduje ze składnią klas ES6, dlatego React wybrał className.

Jak dodać wiele klas w JSX?

Użyj tekstów szablonowych lub biblioteki classnames: className={`“btn ${isActive ? 'active' : ''}”`}. Dla złożonej logiki dołącz pakiet npm clsx lub classnames, które przyjmują obiekty i tablice.

Czy JSX obsługuje konstrukcje warunkowe?

JSX obsługuje tylko wyrażenia, nie instrukcje. Dla warunków używaj operatora trójargumentowego, logicznego AND (&&) lub logicznego OR (||). Dla złożonej logiki wydziel warunek do osobnej zmiennej lub funkcji.

Dlaczego w JSX potrzebny jest key dla list?

Atrybut key pomaga React identyfikować elementy listy podczas ponownego renderowania. Bez klucza React przerysowuje całą listę przy zmianie. Z unikalnym kluczem React ponownie wykorzystuje węzły DOM i zmienia kolejność elementów zamiast je odtwarzać.

Podsumowanie

  • JSX — rozszerzenie JavaScript wzorowane na XML do deklaratywnego opisywania UI, alternatywa dla szablonów tekstowych.
  • Nawiasy klamrowe umożliwiają osadzanie dowolnych wyrażeń JS — zmiennych, funkcji, operatorów trójargumentowych.
  • Atrybuty w JSX zapisuje się w camelCase, style przekazuje się jako obiekt, atrybuty boolowskie — jawnie.
  • Transpilacja JSX do createElement jest wykonywana przez Babel lub TypeScript automatycznie.
  • Jeden główny element lub fragment jest obowiązkowy dla każdego wyrażenia JSX.
  • JSX poza React — SolidJS, Preact, Vue i Qwik również obsługują JSX przez własne środowiska uruchomieniowe.
  • TypeScript z rozszerzeniem .tsx zapewnia pełne typowanie propsów i atrybutów JSX.

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również