JSX — är ett XML-liknande tillägg till JavaScript-syntaxen, utvecklat av React-teamet för deklarativ beskrivning av användargränssnitt. Till skillnad från mallmotorer kompileras JSX till vanliga anrop av JavaScript-funktioner, vilket ger språkets fulla kraft inom märkspråket. Enligt React, 2024 stöds JSX i alla moderna React-ramverk och -bibliotek.
Huvudpunkter
JSX (JavaScript XML) — ett syntaxtillägg för JavaScript, som först introducerades i React 2013. Det gör det möjligt för utvecklare att beskriva strukturen i användargränssnittet på ett deklarativt sätt, genom att kombinera märkspråk och logik i en fil.
Före JSX använde utvecklare textmallar (Mustache, Handlebars) eller skapade manuellt DOM-element via document.createElement. Båda metoderna hade nackdelar: textmallar kontrollerades inte för typer och manuell DOM-skapning var krånglig och felbenägen.
React valde en annan väg — att bädda in märkspråk direkt i koden. Detta beslut orsakade debatt i communityn men blev med tiden en standard. Idag används JSX inte bara i React, utan också i SolidJS, Preact, Qwik och till och med i Vue via plugins.
Ett JSX-element ser ut som en HTML-tagg, men bäddas in direkt i JavaScript. Varje element transpileras till ett anrop av React.createElement med tre argument: elementets typ, props-objektet och underordnade element. Ett rotelement — en obligatorisk regel: ett JSX-uttryck måste returnera ett föräldraelement eller fragment.
import React from 'react';
// Grundläggande JSX - ett rotelement
const element = (
<div className="app">
<h1>Hello, World!</h1>
<p>Welcome to React</p>
</div>
);
När ingen extra DOM-nod behövs, använd React.Fragment eller den korta syntaxen <></>. Fragment skapar inget verkligt DOM-element, utan grupperar bara underordnade noder. Detta är särskilt användbart i tabeller och listor, där en extra wrapper skulle störa HTML-strukturen.
function Columns() {
return (
<>
<td>First</td>
<td>Second</td>
</>
);
}
Varje JavaScript-uttryck bäddas in i JSX via klammerparenteser { }. Inuti kan variabler, funktionsanrop, ternära operatorer och arraymetoder användas. Villkorlig rendering utförs via den ternära operatorn eller logiskt AND.
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>
);
}
Den viktigaste begränsningen — inuti klammerparenteser kan endast uttryck användas, inte satser. if/else, for, switch kan inte användas — endast den ternära operatorn, logiska operatorer och arraymetoder. Funktionsanrop, inklusive pilfunktioner, är tillåtna.
JSX liknar visuellt HTML, men har grundläggande skillnader. Attribut skrivs i camelCase — className istället för class, onClick istället för onclick, tabIndex istället för tabindex. Detta beror på att JSX transpileras till JavaScript, där bindestreck i egenskapsnamn inte är tillåtet.
| HTML | JSX | Anledning |
|---|---|---|
class="wrapper" | className="wrapper" | class — reserverat ord i JS |
onclick="handle()" | onClick={handle} | camelCase för JS-egenskaper |
style="color: red" | style={{ color: 'red' }} | Stilobjekt istället för sträng |
<input disabled> | <input disabled={true}> | Explicit angivelse av boolean-attribut |
En annan viktig skillnad — självstängande taggar. I HTML kan vissa taggar (br, hr, input) förbli öppna. I JSX måste alla självstängande taggar ha ett avslutande snedstreck: <br />, <input />. SVG-attributnamn konverteras också till camelCase: strokeWidth, fillOpacity.
Webbläsare förstår inte JSX direkt. Före körning passerar JSX-koden genom en transpilerare — Babel, TypeScript eller esbuild. Varje JSX-element omvandlas till ett anrop av createElement eller jsx/runtime.
// Original JSX
const element = <h1 className="title">Hello</h1>;
// Efter transpilering
const element = React.createElement(
'h1',
{ className: 'title' },
'Hello'
);
Från och med React 17 har en ny JSX-transformation dykt upp som inte kräver import av React. Automatisk import av jsx-runtime gör det möjligt att skriva komponenter utan import React from 'react'. Babel och TypeScript stöder denna transformation via inställningen {"runtime": "automatic"}.
Även om JSX förknippas med React, använder andra ramverk det också. SolidJS använder JSX med kompilering till riktiga DOM-noder, utan Virtual DOM. Preact — ett lättviktigt alternativ till React med fullt stöd för JSX. Vue stöder JSX via @vue/babel-plugin-jsx, även om dess primära mall är template.
Den viktigaste skillnaden — semantik av uttryck. I React körs JSX-uttryck vid varje rendering. I SolidJS kompileras JSX en gång och uppdateringar spåras via signaler. Detta påverkar prestandan: SolidJS kräver inte Virtual DOM och reconciliering, så JSX-rendering är snabbare.
I TypeScript stöds JSX på språknivå. Filer med tillägget .tsx bearbetar automatiskt JSX-syntax. Typning av props — en av de främsta fördelarna med TypeScript + JSX: IDE föreslår förväntade attribut, callback-typer och obligatoriska props.
Skriv JSX-kod som är lätt att läsa och underhålla. Flytta komplexa uttryck till separata variabler eller funktioner — detta förbättrar läsbarheten och gör det möjligt att testa logiken separat från märkspråket. Använd fragment istället för onödiga div-omslag.
Regeln om indrag — håll indrag för nästlade element. Varje nästlingsnivå — en indragsnivå. Den avslutande taggen ska vara på samma nivå som den öppnande. För långa attribut, använd radbrytning.
Undvik inline pilfunktioner i props, om de skapas vid varje rendering. I sådana fall, linda in callback i useCallback eller placera funktionen utanför komponenten. Dela upp komplexa komponenter i mindre — varje komponent bör ansvara för en logisk enhet av gränssnittet.
Vanliga frågor
Ja, via Babel-plugin @babel/plugin-transform-react-jsx kan JSX konfigureras för vilket bibliotek som helst. SolidJS, Preact, Nerv och andra ramverk använder JSX med egna runtime. För fullständigt oberoende kan pragma ställas in på en egen funktion.
class är ett reserverat ord i JavaScript. JSX transpileras till createElement, där det andra argumentet är ett props-objekt. Egenskapen class kolliderar med klassyntaxen i ES6, därför valde React className.
Använd template strings eller biblioteket classnames: className={`“btn ${isActive ? 'active' : ''}”`}. För komplex logik, anslut npm-paketet clsx eller classnames, som accepterar objekt och arrayer.
JSX stöder endast uttryck, inte satser. För villkor, använd den ternära operatorn, logiskt AND (&&) eller logiskt OR (||). För komplex logik, flytta villkoret till en separat variabel eller funktion.
Attributet key hjälper React att identifiera listelement vid omrendering. Utan key ritar React om hela listan vid förändring. Med en unik key återanvänder React DOM-noder och ordnar om element istället för att återskapa dem.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också