JSX es una extensión de sintaxis de JavaScript que te permite escribir código similar a HTML directamente dentro de tus archivos .js o .jsx.
React transforma ese código en instrucciones JavaScript puras antes de que el navegador lo ejecute. No es HTML real, pero se parece tanto que resulta fácil de leer y mantener.
Qué es JSX exactamente
JSX significa JavaScript XML. Es una sintaxis especial que Babel (la herramienta que usa React internamente) convierte en llamadas a React.createElement().
Por ejemplo, esto en JSX:
const elemento = <h1>Bienvenido a Liverpool</h1>;
Se convierte internamente en esto:
const elemento = React.createElement("h1", null, "Bienvenido a Liverpool");
Tú escribes JSX porque es más legible. React hace la conversión automáticamente.
Estructura básica de JSX
Un bloque JSX válido sigue estas reglas:
- Un solo elemento raíz. Todo el JSX debe estar envuelto en un único contenedor.
- Etiquetas siempre cerradas. Incluye las etiquetas que en HTML normal no se cierran.
- Atributos en camelCase. Los atributos de HTML cambian de nombre en JSX.
- Expresiones con llaves
{}. Para insertar JavaScript dentro del JSX, usa llaves.
Plantilla general:
function MiComponente() {
return (
<ContenedorRaíz>
<Elemento atributo={valor} />
</ContenedorRaíz>
);
}
Regla 1: Un solo elemento raíz
Todo el JSX que retorna un componente debe tener exactamente un elemento padre.
Esto genera error:
// ❌ Incorrecto
function Encabezado() {
return (
<h1>FEMSA</h1>
<p>Bebidas y energía</p>
);
}
Esto funciona con un <div>:
// ✅ Correcto con div
function Encabezado() {
return (
<div>
<h1>FEMSA</h1>
<p>Bebidas y energía</p>
</div>
);
}
O puedes usar un Fragment para no agregar nodos extra al DOM:
// ✅ Correcto con Fragment
function Encabezado() {
return (
<>
<h1>FEMSA</h1>
<p>Bebidas y energía</p>
</>
);
}
El Fragment <>...</> es invisible en el HTML final. No agrega ninguna etiqueta extra.
Regla 2: Etiquetas siempre cerradas
En JSX, toda etiqueta debe cerrarse, incluso las que en HTML5 no lo requieren.
En HTML estándar puedes escribir <img> o <input> sin cerrar. En JSX eso rompe el código.
// ❌ Incorrecto en JSX
<img src="logo-bimbo.png">
<input type="text">
<br>
// ✅ Correcto en JSX
<img src="logo-bimbo.png" />
<input type="text" />
<br />
Agrega una barra diagonal antes del > para cerrar la etiqueta en la misma línea.
Regla 3: Atributos en camelCase
JSX usa camelCase para los atributos porque JavaScript no acepta guiones en nombres de propiedades.
Esta tabla muestra los cambios más comunes:
| HTML estándar | JSX equivalente |
|---|---|
class |
className |
for |
htmlFor |
onclick |
onClick |
onchange |
onChange |
tabindex |
tabIndex |
readonly |
readOnly |
maxlength |
maxLength |
style="color: red" |
style={{ color: "red" }} |
Ejemplo práctico con un formulario de Mercado Libre:
function BuscadorML() {
return (
<div className="buscador">
<label htmlFor="busqueda">¿Qué estás buscando?</label>
<input
id="busqueda"
type="text"
maxLength={100}
onChange={(e) => console.log(e.target.value)}
/>
</div>
);
}
Nota que onChange va en camelCase y recibe una función entre llaves.
Regla 4: Insertar JavaScript con llaves {}
Las llaves {} te permiten evaluar cualquier expresión de JavaScript dentro del JSX.
Puedes insertar variables, cálculos, llamadas a funciones y operadores ternarios.
Ejemplo 1 — Variable simple
function PrecioProducto() {
const precio = 349;
const descuento = 50;
return (
<div>
<p>Precio original: ${precio}</p>
<p>Precio con descuento: ${precio - descuento}</p>
</div>
);
}
Salida en pantalla:
Precio original: $349
Precio con descuento: $299
Ejemplo 2 — Operador ternario para mostrar u ocultar
Un caso muy frecuente es mostrar contenido según una condición.
function EstadoPedido() {
const enviado = true;
return (
<div>
<h2>Tu pedido de Liverpool</h2>
<p>{enviado ? "✅ Tu pedido ya fue enviado" : "⏳ En preparación"}</p>
</div>
);
}
Si enviado es true, el usuario ve el mensaje de confirmación. Si es false, ve el mensaje de espera.
Ejemplo 3 — Estilos en línea con doble llave
En JSX, los estilos en línea se escriben como un objeto de JavaScript. Necesitas doble llave: una para la expresión JSX y otra para el objeto.
function TarjetaBimbo() {
const colorMarca = "#e30613";
return (
<div style={{ backgroundColor: colorMarca, padding: "16px", borderRadius: "8px" }}>
<p style={{ color: "white", fontWeight: "bold" }}>Bimbo — Pan de calidad</p>
</div>
);
}
Nota que los valores de estilo son cadenas de texto entre comillas, y las propiedades van en camelCase (backgroundColor, borderRadius).
Diferencias clave entre JSX y HTML
| Característica | HTML estándar | JSX |
|---|---|---|
| Atributo de clase | class |
className |
| Atributo de etiqueta | for |
htmlFor |
| Etiquetas vacías | <br>, <img> |
<br />, <img /> |
| Estilos en línea | style="color: red" |
style={{ color: "red" }} |
| Comentarios | <!-- comentario --> |
{/* comentario */} |
| Elemento raíz | Opcional | Obligatorio |
| Eventos | onclick |
onClick |
Los comentarios dentro de JSX también usan llaves. Así se escriben:
function Componente() {
return (
<div>
{/* Este comentario no aparece en pantalla */}
<p>Contenido visible</p>
</div>
);
}
Errores comunes
Error 1: Usar class en lugar de className
// ❌ Genera advertencia y puede fallar
<div class="contenedor">...</div>
// ✅ Correcto
<div className="contenedor">...</div>
React mostrará una advertencia en consola si usas class. El componente puede renderizarse, pero no aplicará los estilos correctamente en todos los casos.
Error 2: Retornar JSX sin paréntesis en varias líneas
Cuando el JSX ocupa más de una línea, siempre envuelve el return con paréntesis.
// ❌ JavaScript interpreta el return como vacío
function Tarjeta() {
return
<div>
<p>Hola</p>
</div>;
}
// ✅ Correcto
function Tarjeta() {
return (
<div>
<p>Hola</p>
</div>
);
}
Sin paréntesis, JavaScript agrega un punto y coma automático después de return y el componente no muestra nada.
Error 3: Poner sentencias if directamente dentro del JSX
Dentro de las llaves {} solo puedes usar expresiones, no sentencias. Un if clásico es una sentencia y no funciona ahí.
// ❌ Esto genera error de sintaxis
function Saludo() {
const usuario = "Ana";
return (
<div>
{if (usuario) { <p>Hola {usuario}</p> }}
</div>
);
}
// ✅ Usa el operador ternario o &&
function Saludo() {
const usuario = "Ana";
return (
<div>
{usuario && <p>Hola {usuario}</p>}
</div>
);
}
El operador && muestra el elemento solo si la condición es verdadera. Es la forma más corta de hacer un "if" en JSX.
Error 4: Olvidar cerrar etiquetas
// ❌ Falta cerrar el input
<input type="email">
// ✅ Correcto
<input type="email" />
Babel lanzará un error de compilación inmediato. Tu app dejará de funcionar hasta que lo corrijas.
Resumen de las reglas JSX
| Regla | Descripción |
|---|---|
| Un elemento raíz | Usa <div> o <>...</> para agrupar |
| Etiquetas cerradas | Agrega / antes del > en etiquetas vacías |
| camelCase | className, onClick, onChange, htmlFor |
Expresiones con {} |
Variables, ternarios, funciones, pero no if |
Estilos con {{}} |
El estilo es un objeto JS dentro de JSX |
Comentarios con {/* */} |
No uses <!-- --> dentro de JSX |