JSX (JavaScript XML) to rozszerzenie składni JavaScript, które pozwala pisać kod przypominający HTML bezpośrednio w JavaScript. Jest to deklaratywny sposób opisywania, jak powinna wyglądać struktura UI w React.
Dla programisty, który dopiero zaczyna przygodę z React, JSX może wydawać się dziwny - jak to możliwe, że nagle w środku JavaScript'u pojawiają się znaczniki HTML?
Wyobraź sobie JSX jako tłumacza między światem JavaScript a światem HTML. Pozwala opisać strukturę UI w sposób, który jest czytelny dla ludzi (podobny do HTML), ale jednocześnie zachowuje całą moc JavaScript.
Ważne jest, aby zrozumieć, że przeglądarki nie rozumieją JSX natively. Zanim kod trafi do przeglądarki, jest kompilowany do zwykłego JavaScript'u przez narzędzia takie jak Babel.
Przykładowo, ten kod JSX:
1const element = <h1>Witaj, świecie!</h1>;Jest transformowany na:
1const element = React.createElement(
2 'h1',
3 null,
4 'Witaj, świecie!'
5);To właśnie dlatego zawsze importujemy React na początku plików z JSX, nawet jeśli nie używamy go bezpośrednio -
React.createElement jest używane za kulisami.JSX może wydawać się jak HTML, ale ma kilka unikalnych cech i zasad, które warto zrozumieć:
W przeciwieństwie do HTML, gdzie atrybuty są pisane małymi literami, w JSX wiele atrybutów jest zapisywanych w formacie camelCase:
1// HTML
2<div onclick="handleClick()" tabindex="0" class="container">
3
4// JSX
5<div onClick={handleClick} tabIndex={0} className="container">Zwróć uwagę na różnice:
onclick -> onClicktabindex -> tabIndexclass -> className (ponieważ "class" jest zarezerwowanym słowem w JavaScript)W JSX, wartości atrybutów nie są zawsze stringami. Możesz używać dowolnych wyrażeń JavaScript, ujmując je w nawiasy klamrowe:
1// Wartość liczbowa
2<input maxLength={10} />
3
4// Wyrażenie
5<img src={user.avatarUrl} />
6
7// Ternary operator (operator warunkowy)
8<div className={isActive ? 'active' : 'inactive'}>
9
10// Funkcja
11<button onClick={handleClick}>W JSX, tagi bez dzieci (children) muszą mieć ukośnik zamykający:
1// HTML
2<input type="text">
3
4// JSX
5<input type="text" />W HTML niektóre tagi mogą pozostać niezamknięte (np.
<img>, <br>), ale w JSX wszystkie tagi muszą być prawidłowo zamknięte:1// Niepoprawne w JSX
2<img src="logo.png">
3
4// Poprawne w JSX
5<img src="logo.png" />JSX wymaga, aby zwracać tylko jeden element nadrzędny. Jeśli chcesz zwrócić wiele elementów, musisz je opakować w kontener:
1// Niepoprawne w JSX
2function Component() {
3 return (
4 <h1>Tytuł</h1>
5 <p>Paragraf</p>
6 );
7}
8
9// Poprawne w JSX
10function Component() {
11 return (
12 <div>
13 <h1>Tytuł</h1>
14 <p>Paragraf</p>
15 </div>
16 );
17}Jeśli nie chcesz wprowadzać dodatkowego elementu DOM, możesz użyć Fragment:
1function Component() {
2 return (
3 <>
4 <h1>Tytuł</h1>
5 <p>Paragraf</p>
6 </>
7 );
8}Możesz używać wyrażeń JavaScript w JSX, umieszczając je w nawiasach klamrowych
{}:1function Greeting({ user }) {
2 return (
3 <div>
4 {/* Wyrażenie warunkowe */}
5 {user ? <h1>Witaj, {user.name}!</h1> : <h1>Witaj, nieznajomy!</h1>}
6
7 {/* Wykonywanie obliczeń */}
8 <p>Twoje konto zostało utworzone {calculateDaysAgo(user.createdAt)} dni temu</p>
9
10 {/* Mapowanie listy */}
11 <ul>
12 {user.hobbies.map(hobby => (
13 <li key={hobby.id}>{hobby.name}</li>
14 ))}
15 </ul>
16 </div>
17 );
18}Możesz używać spread operatora (
...), aby przekazać wszystkie właściwości obiektu jako props:1const buttonProps = {
2 type: 'submit',
3 disabled: false,
4 className: 'primary-button'
5};
6
7<button {...buttonProps}>Wyślij</button>Możesz dynamicznie określać atrybuty elementów:
1const inputType = isPassword ? 'password' : 'text';
2<input type={inputType} />JSX oferuje kilka sposobów na warunkowe renderowanie elementów:
1// 1. Używając operatora trójskładnikowego
2{isLoggedIn ? <UserProfile /> : <LoginButton />}
3
4// 2. Używając operatora logicznego &&
5{isLoggedIn && <WelcomeMessage />}
6
7// 3. Używając zmiennej
8let button;
9if (isLoggedIn) {
10 button = <LogoutButton />;
11} else {
12 button = <LoginButton />;
13}
14return <div>{button}</div>;W JSX, style inline są definiowane jako obiekty JavaScript:
1const divStyle = {
2 color: 'blue',
3 backgroundColor: 'lightgray',
4 padding: '10px',
5 // Zauważ, że właściwości z myślnikiem (jak background-color)
6 // są zapisywane w camelCase (backgroundColor)
7};
8
9<div style={divStyle}>Stylizowany tekst</div>
10
11// Albo bezpośrednio w JSX
12<div style={{ fontWeight: 'bold', fontSize: '16px' }}>Pogrubiony tekst</div>Komentarze w JSX są umieszczane wewnątrz nawiasów klamrowych i używają składni komentarzy JavaScript:
1<div>
2 {/* To jest komentarz w JSX */}
3 <h1>Tytuł</h1>
4 {/*
5 Możesz również używać
6 komentarzy wieloliniowych
7 */}
8</div>JSX nie renderuje logicznych wartości, null i undefined:
1// Te wyrażenia nie renderują nic na ekranie
2<div>{true}</div>
3<div>{false}</div>
4<div>{null}</div>
5<div>{undefined}</div>
6
7// Ale liczby i stringi są renderowane
8<div>{0}</div>
9<div>{"string"}</div>Pamiętaj, że cudzysłowy są używane dla wartości łańcuchowych, a nawiasy klamrowe dla wyrażeń JavaScript:
1// Poprawnie
2<input type="text" maxLength={10} />
3
4// Niepoprawnie
5<input type={text} maxLength="10" /> // błąd: 'text' nie jest zdefiniowanyNie możesz używać instrukcji if/else bezpośrednio w JSX, ponieważ JSX jest wyrażeniem, a nie instrukcją:
1// Niepoprawne
2<div>
3 {if (isLoggedIn) {
4 return <UserProfile />;
5 } else {
6 return <LoginButton />;
7 }}
8</div>
9
10// Poprawne - użyj operatora trójskładnikowego
11<div>
12 {isLoggedIn ? <UserProfile /> : <LoginButton />}
13</div>JSX jest jednym z najważniejszych aspektów React, który znacznie ułatwia tworzenie interfejsów użytkownika. Dzięki JSX, możesz:
Pamiętaj, że JSX to tylko składnia, która jest przekształcana do wywołań
React.createElement(). Zrozumienie zasad i możliwości JSX jest kluczowe dla efektywnego programowania w React.