Skip to content
This page has been auto-translated and may contain errors.View in English

JSX

Construir incluso una pequeña pieza de interfaz con JavaScript puro implica hacer malabares con pasos separados: crear un elemento, asignarle una clase, establecer su texto, luego adjuntarlo a la página. El markup y el código que lo maneja viven en lugares distintos, y mantenerlos sincronizados se vuelve más difícil conforme la UI crece. JSX cierra esa brecha: el markup vive directamente dentro de tu JavaScript, lo suficientemente cerca para que puedas mezclarlos libremente en lugar de mantener templates y scripts separados.

Markup dentro de JavaScript

Porque JSX es JavaScript, puedes insertar cualquier expresión de JavaScript en él envolviendo la en llaves, {}. Una variable, una llamada a función, un poco de matemáticas, cualquier valor que necesites, va directamente en el markup donde de otro modo escribirías texto estático.

jsx
const name = 'Carlos'
return <p className="greeting">Hola, {name}</p>

Aquí {name} se reemplaza con el valor de la variable name cuando esto se renderiza, así que la página muestra "Hola, Carlos". Fuera de las llaves, todo es markup; dentro de ellas, vuelves a estar en JavaScript puro.

JSX trae consigo unas pocas reglas. La mayoría de los atributos usan camelCase en lugar de los nombres en minúsculas y con guiones que usa HTML, así que es className, htmlFor y tabIndex en lugar de class, for y tabindex, mientras que los atributos ARIA y data- conservan sus guiones, como en aria-hidden y data-testid. Cada tag debe estar cerrado, incluidos los que se dejarían abiertos en HTML, así que <img /> y <br /> necesitan esa barra de cierre. Y un componente solo puede retornar un elemento raíz. Si necesitas retornar dos elementos uno al lado del otro sin envolverlos en un <div> extra, envuélvelos en un fragment, escrito como corchetes angulares vacíos:

jsx
return (
  <>
    <h1>Título</h1>
    <p>Algo de texto</p>
  </>
)

Cómo JSX difiere de HTML

JSX se parece lo suficiente a HTML como para que las diferencias sean tan sutiles que las pasas por alto hasta que te atrapan. Los nombres de los atributos son la primera: class se convierte en className, porque class es una palabra reservada en JavaScript. El atributo style es otro: en HTML es una cadena de CSS, pero en JSX toma un objeto de JavaScript, con nombres de propiedad en camelCase y valores como cadenas.

jsx
<div style={{ backgroundColor: 'lightblue', fontSize: '18px' }}>Estilizado</div>

Las llaves externas {} son las mismas que incrustan cualquier expresión, y las llaves internas {} son el literal de objeto siendo incrustado, lo cual es por qué un atributo style en JSX termina con dos llaves seguidas.

La otra diferencia es lo que está permitido dentro de {}. Solo acepta expresiones, cosas que producen un valor, como una variable, una llamada a función, o un operador ternario. No acepta sentencias, así que un if o un bucle for no puede ir directamente dentro de llaves en tu markup. Cuando necesitas ese tipo de lógica, la ejecutas arriba del return e incrustas el resultado en su lugar.

Entre bastidores, JSX se compila a llamadas de función JavaScript planas antes de llegar al navegador. Ese es un detalle de tooling más que algo en lo que pienses día a día, y el capítulo Beyond the basics vuelve a esto una vez que el resto de React está en su lugar.

JSX es azúcar sintáctico. El compilador convierte cada elemento en una llamada a React.createElement o, con el JSX runtime automático que usa el tooling de esta pista (estándar desde React 17, y el default que obtendrás con cualquier setup moderno), una llamada equivalente generada por la herramienta de construcción sin que necesites React en scope. Ese ejemplo anterior se compila a algo cercano a React.createElement('p', { className: 'greeting' }, 'Hola, ', name).

Ese paso de compilación es exactamente por qué {} solo contiene expresiones. Cada {} se convierte en un argumento pasado a esa llamada de función, y un argumento de función debe evaluarse a un valor. Una sentencia como if o for no produce un valor, así que no puede estar donde se espera un argumento. Un ternario funciona en línea porque es una expresión; un if no, porque es una sentencia. Cuando la lógica es más de lo que un ternario puede contener limpiamente, calcula el valor en una variable arriba del return e incrust esa variable en su lugar.

JunoJSX es markup con JavaScript mezclado Lo principal a retener: {} es tu puerta de regreso a JavaScript desde dentro del markup. Cualquier cosa entre esas llaves es un valor, una variable, un cálculo, una llamada a función, y se inserta directamente en la página. Todo lo demás viene de ahí: className en lugar de class, cerrar cada tag, y un elemento raíz por return.
JunoJSX es markup con JavaScript mezclado Trata {} como tu slot para expresiones: variables, llamadas a funciones, operadores ternarios, todo está bien, sentencias como if no. Combina eso con las diferencias de nombres, className, htmlFor, style como un objeto, y JSX deja de sentirse como una variante de HTML y comienza a sentirse como lo que es, JavaScript con sintaxis de markup.
JunoJSX es markup con JavaScript mezclado Cada {} se compila en un argumento de función, que es la razón completa por la que las expresiones funcionan ahí y las sentencias no. Mantén ese modelo mental y el resto de las peculiaridades de JSX, atributos en camelCase, el objeto style, tags auto-cerrables, dejan de parecer reglas arbitrarias y comienzan a parecer consecuencias de "esto son llamadas a React.createElement disfrazadas."

Siguiente: Styling components, donde esos elementos obtienen su apariencia.