JSX (JavaScript XML) es una extensión de sintaxis para JavaScript creada por el equipo de React para ara facilitar la escritura de componentes.
JSN permite escribir estructura de componentes similar a HTML dentro del código JavaScript, combinando ambos lenguajes de forma más intuitiva.
- Es muy legible: JSX se parece a HTML, lo que facilita la comprensión del código.
- Es más expresivo: Permite describir la estructura de la interfaz de usuario de manera declarativa.
- Es más seguro: JSX previene ciertos tipos de errores e incluso problemas se seguridad.
Es una mezcla entre HTML y JavaScript que puede parecer confusa al principio, pero es una de las características más distintivas de React (y una de las razones por las que es tan popular).
Veamos un ejemplo de JSX y esta “mezcla de lenguajes JavaScript y HTML”
const elemento = <h1>Hola, mundo!</h1>;
En este ejemplo,
elemento
es una variable que contiene un fragmento de JSX.- Como véis, no he necesitado poner
"
, ni nada así (porque no es un string, es un fragmento de JSX)
No es obligatorio usarlo en React, pero es altamente recomendado debido a su claridad y seguridad.
Reglas básicas de sintaxis JSX
Como decíamos, JSX se parece mucho a HTML, pero no es exactamtente HTML (es su propia sintaxis).
Por tanto, tiene sus propias reglas y algunas (pocas) diferencias importantes . Aquí van las principales:
JSX permite usar etiquetas HTML estándar, como <div>
, <h1>
, <p>
, etc. Sin embargo, hay algunas diferencias clave:
- JSX requiere que todas las etiquetas estén cerradas, incluso las que en HTML no lo necesitan (como
<br>
,<img>
,<input>
).
// ❌ Incorrecto
<img src="foto.jpg">
// ✅ Correcto
<img src="foto.jpg" />
- Etiquetas personalizadas: JSX permite usar nombres de componentes personalizados, que deben comenzar con una letra mayúscula.
<MiComponente />
En JSX cada componente o fragmento debe retornar un solo nodo padre. Por ejemplo, esto es incorrecto:
// ❌ Esto da error
return (
<h1>Título</h1>
<p>Descripción</p>
);
Para solucionarlo, puedes envolver todo en un <div>
:
// ✅ Correcto
return (
<div>
<h1>Título</h1>
<p>Descripción</p>
</div>
);
O usar un Fragmento (<>...</>
), que no añade nodos extra al DOM:
return (
<>
<h1>Título</h1>
<p>Descripción</p>
</>
);
En lugar de usar atributos HTML clásicos (class
, for
, etc.), JSX usa nombres en camelCase siguiendo las convenciones de JavaScript.
HTML | JSX |
---|---|
class | className |
for | htmlFor |
onclick | onClick |
// ❌ Incorrecto
<div class="contenedor"></div>
// ✅ Correcto
<div className="contenedor"></div>
Los comentarios en JSX se escriben dentro de llaves {}
y usan la sintaxis de comentarios de JavaScript (/* ... */
).
<div>
{/* Este es un comentario en JSX */}
<p>Hola, mundo!</p>
</div>
JSX y expresividad con JavaScript
JSX no es una plantilla estática: es código JavaScript embebido con sintaxis parecidas a HTML… pero sigue siendo JavaScript.
Por tanto, puedes usar variables y expresiones dentro de los fragmentos de “HTML” (es la mayor parte de la gracia de JSX).
Para ello, puedes pasar strings, variables, o incluso objetos. Por ejemplo,
const usuario = {
nombre: "Luis",
edad: 22
};
return (
<div>
<h2>Perfil</h2>
<p>Nombre: {usuario.nombre}</p> // esto imprime "Luis"
<p>Edad: {usuario.edad}</p> // esto imprime "22"
</div>
);
Al final, no deja de ser una interpolación de cadenas bajo el capo, con un poco de syntatic sugar (más bien, con mucho syntatic sugar).
De igual forma, puedes usar variables y expresiones en de atributos del HTML. Por ejemplo, para la clase (o cualquier otro),
const titulo = "Hola";
const clase = "rojo";
return (
<h1 className={clase}>{titulo} mundo</h1>
);
Incluso, dentro de {}
puedes poner operaciones, funciones, o casi cualquier expresion de JavaScript. Por ejemplo,:
const nombre = "Ana";
return <p>Hola, {nombre.toUpperCase()}!</p>;
Aunque conviene que no te vuelvas loco poniendo cosas larguisimas dentro de las {}
. Si lo necesitas, crea una variable independiente.
Composicion de componentes
Hemos mencionado que JSX permite añadir nuevas etiquetas (que son precisamente los componentes que vamos a crear en React).
Por extensión, también podemos componer componentes como si fueran etiquetas HTML. Es decir, si tienes un componente Boton
, puedes usarlo así:
function Boton() {
return <button>Haz clic</button>;
}
function App() {
return (
<div>
<h1>Bienvenido</h1>
<Boton />
</div>
);
}
Fíjate que los nombres de componentes personalizados siempre deben empezar con mayúscula (<Boton />
, no <boton />
), para que React los distinga de las etiquetas HTML.
Funcionamiento interno Avanzado
Aunque no lo veamos, bajo el capó, todo nuestro JSX se transforma en código JavaScript estandard, totalmente compatible con el navegador.
En concreto, se convierte en llamadas a React.createElement
. Por ejemplo, el siguiente código JSX:
const elemento = <h1 className="titulo">Hola, mundo!</h1>;
Se transformará en:
const elemento = React.createElement(
"h1",
{ className: "titulo" },
"Hola, mundo!"
);
Que, estaremos de acuerdo que es mucho menos legible, y no nos apetecería escribir a mano (¿verdad? 🤭)
Esta transformación es realizada por herramientas como Babel o ESBuilt o similar, que se encargan de realizar estas operaciones de forma transparente para nosotros.
Nosotros estamos usando Vite, que internamente usa ESBuilt para la conversión.