JSX — este o extensie de sintaxă asemănătoare XML pentru JavaScript, dezvoltată de echipa React pentru descrierea declarativă a interfețelor de utilizator. Spre deosebire de motoarele de șabloane, JSX este compilat în apeluri obișnuite de funcții JavaScript, oferind puterea deplină a limbajului în interiorul marcajului. Conform React, 2024, JSX este suportat în toate framework-urile și bibliotecile React moderne.
Principalele puncte
JSX (JavaScript XML) — o extensie de sintaxă pentru JavaScript, introdusă pentru prima dată în React în 2013. Permite dezvoltatorilor să descrie structura interfeței de utilizator într-un stil declarativ, combinând marcajul și logica într-un singur fișier.
Înainte de apariția JSX, dezvoltatorii foloseau șabloane text (Mustache, Handlebars) sau creau manual elemente DOM prin document.createElement. Ambele abordări aveau dezavantaje: șabloanele text nu erau verificate tipologic, iar crearea manuală a DOM era greoaie și predispusă la erori.
React a ales o altă cale — încorporarea marcajului direct în cod. Această decizie a stârnit controverse în comunitate, dar în timp a devenit un standard. Astăzi, JSX este folosit nu numai în React, ci și în SolidJS, Preact, Qwik și chiar în Vue prin pluginuri.
Un element JSX arată ca o etichetă HTML, dar este încorporat direct în JavaScript. Fiecare element este transpilat într-un apel React.createElement cu trei argumente: tipul elementului, obiectul de props și elementele copil. Un element rădăcină — o regulă obligatorie: expresia JSX trebuie să returneze un element părinte sau un fragment.
import React from 'react';
// JSX de bază - un singur element rădăcină
const element = (
<div className="app">
<h1>Hello, World!</h1>
<p>Welcome to React</p>
</div>
);
Când nu este nevoie de un nod DOM suplimentar, utilizați React.Fragment sau sintaxa scurtă <></>. Fragmentele nu creează un element DOM real, ci doar grupează nodurile copil. Acest lucru este util în special în tabele și liste, unde un înveliș suplimentar ar perturba structura HTML.
function Columns() {
return (
<>
<td>First</td>
<td>Second</td>
</>
);
}
Orice expresie JavaScript se încorporează în JSX prin acolade { }. În interior se pot folosi variabile, apeluri de funcții, operatori ternari și metode de array. Randarea condiționată se realizează prin operatorul ternar sau AND logic.
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>
);
}
Limitarea cheie — în interiorul acoladelor se pot folosi doar expresii, nu instrucțiuni. Nu se pot folosi if/else, for, switch — doar operatorul ternar, operatorii logici și metodele de array. Apelurile de funcții, inclusiv funcțiile săgeată, sunt permise.
JSX este vizual similar cu HTML, dar are diferențe fundamentale. Atributele se scriu în camelCase — className în loc de class, onClick în loc de onclick, tabIndex în loc de tabindex. Acest lucru se datorează faptului că JSX este transpilat în JavaScript, unde cratima în numele proprietății nu este permisă.
| HTML | JSX | Motiv |
|---|---|---|
class="wrapper" | className="wrapper" | class — cuvânt rezervat în JS |
onclick="handle()" | onClick={handle} | camelCase pentru proprietăți JS |
style="color: red" | style={{ color: 'red' }} | Obiect de stiluri în loc de șir |
<input disabled> | <input disabled={true}> | Specificare explicită a atributelor booleene |
O altă diferență importantă — etichete auto-închise. În HTML, unele etichete (br, hr, input) pot rămâne neînchise. În JSX, toate etichetele auto-închise trebuie să aibă o bară oblică de închidere: <br />, <input />. Numele atributelor SVG sunt de asemenea convertite în camelCase: strokeWidth, fillOpacity.
Browserele nu înțeleg JSX direct. Înainte de execuție, codul JSX trece printr-un transpiler — Babel, TypeScript sau esbuild. Fiecare element JSX se transformă într-un apel createElement sau jsx/runtime.
// JSX original
const element = <h1 className="title">Hello</h1>;
// După transpilare
const element = React.createElement(
'h1',
{ className: 'title' },
'Hello'
);
Începând cu React 17, a apărut o nouă transformare JSX care nu necesită importarea React. Importul automat jsx-runtime permite scrierea de componente fără import React from 'react'. Babel și TypeScript suportă această transformare prin setarea {"runtime": "automatic"}.
Deși JSX este asociat cu React, și alte framework-uri îl folosesc. SolidJS folosește JSX cu compilare în noduri DOM reale, fără Virtual DOM. Preact — o alternativă ușoară la React cu suport complet pentru JSX. Vue suportă JSX prin @vue/babel-plugin-jsx, deși șablonul său principal este template.
Diferența cheie — semantica expresiilor. În React, expresiile JSX sunt executate la fiecare randare. În SolidJS, JSX este compilat o singură dată, iar actualizările sunt urmărite prin semnale. Aceasta afectează performanța: SolidJS nu necesită Virtual DOM și reconciliere, deci randarea JSX este mai rapidă.
În TypeScript, JSX este suportat la nivel de limbaj. Fișierele cu extensia .tsx procesează automat sintaxa JSX. Tipizarea props — unul dintre avantajele principale ale TypeScript + JSX: IDE sugerează atributele așteptate, tipurile de callback și obligativitatea props.
Scrieți cod JSX ușor de citit și întreținut. Extrageți expresiile complexe în variabile sau funcții separate — aceasta îmbunătățește lizibilitatea și permite testarea logicii separat de marcaj. Folosiți fragmente în loc de învelișuri div inutile.
Regula indentării — respectați indentarea pentru elementele imbricate. Fiecare nivel de imbricare — un nivel de indentare. Eticheta de închidere trebuie să fie la nivelul celei de deschidere. Pentru atribute lungi, folosiți întreruperea de linie.
Evitați funcțiile săgeată inline în props, dacă sunt create la fiecare randare. În astfel de cazuri, înfășurați callback-ul în useCallback sau scoateți funcția în afara componentului. Împărțiți componentele complexe în altele mai mici — fiecare componentă ar trebui să fie responsabilă pentru o unitate logică a interfeței.
Întrebări frecvente
Da, prin pluginul Babel @babel/plugin-transform-react-jsx se poate configura JSX pentru orice bibliotecă. SolidJS, Preact, Nerv și alte framework-uri folosesc JSX cu propriile runtime-uri. Pentru independență completă, se poate seta pragma pe propria funcție.
class este un cuvânt rezervat în JavaScript. JSX este transpilat în createElement, unde al doilea argument este un obiect de props. Proprietatea class intră în conflict cu sintaxa claselor ES6, de aceea React a ales className.
Folosiți șabloane de șiruri sau biblioteca classnames: className={`“btn ${isActive ? 'active' : ''}”`}. Pentru logică complexă, conectați pachetul npm clsx sau classnames, care acceptă obiecte și array-uri.
JSX suportă doar expresii, nu instrucțiuni. Pentru condiții, folosiți operatorul ternar, AND logic (&&) sau OR logic (||). Pentru logică complexă, extrageți condiția într-o variabilă sau funcție separată.
Atributul key ajută React să identifice elementele listei la rerandare. Fără key, React redesenează întreaga listă la modificare. Cu un key unic, React reutilizează nodurile DOM și reordonează elementele în loc să le recreeze.
Rezumat
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și