Escribir marcado con JSX

JSX es una extensión de sintaxis para JavaScript que permite escribir marcas similares a HTML dentro de una archivo JavaScript. Aunque hay otras formas de escribir componentes, la mayoría de los desarrolladores de React prefieren la concisión de JSX, y la mayoría de las bases de código lo usan.

Aprender√°s

  • Por qu√© React mezcla marcado con l√≥gica de renderizado
  • En qu√© se diferencia JSX de HTML
  • C√≥mo mostrar informaci√≥n con JSX

JSX: Poniendo marcado dentro de JavaScript

La Web se ha construido sobre HTML, CSS, y JavaScript. Durante muchos a√Īos, los desarrolladores web mantuvieron el contenido en HTML, el dise√Īo en CSS, y la l√≥gica en JavaScript, ¬°a menudo en archivos separados! El contenido se marc√≥ dentro del HTML mientras que la l√≥gica de la pagina viv√≠a por separado en JavaScript:

HTML markup with purple background and a div with two child tags: p and form.
HTML markup with purple background and a div with two child tags: p and form.

HTML

Three JavaScript handlers with yellow background: onSubmit, onLogin, and onClick.
Three JavaScript handlers with yellow background: onSubmit, onLogin, and onClick.

JavaScript

Pero, a medida que la Web se volvió más interactiva, la lógica determinó cada vez más el contenido. ¡JavaScript estaba a cargo del HTML! Esto es la razón por la que en React, la lógica de renderizado y el marcado viven juntos en el mismo lugar: componentes.

React component with HTML and JavaScript from previous examples mixed. Function name is Sidebar which calls the function isLoggedIn, highlighted in yellow. Nested inside the function highlighted in purple is the p tag from before, and a Form tag referencing the component shown in the next diagram.
React component with HTML and JavaScript from previous examples mixed. Function name is Sidebar which calls the function isLoggedIn, highlighted in yellow. Nested inside the function highlighted in purple is the p tag from before, and a Form tag referencing the component shown in the next diagram.

Componente de React Sidebar.js

React component with HTML and JavaScript from previous examples mixed. Function name is Form containing two handlers onClick and onSubmit highlighted in yellow. Following the handlers is HTML highlighted in purple. The HTML contains a form element with a nested input element, each with an onClick prop.
React component with HTML and JavaScript from previous examples mixed. Function name is Form containing two handlers onClick and onSubmit highlighted in yellow. Following the handlers is HTML highlighted in purple. The HTML contains a form element with a nested input element, each with an onClick prop.

Componente de React Form.js

Mantener juntas la lógica de renderizado y el marcado de un botón, garantiza que permanezcan sincronizados entre sí en cada edición. Por el contrario, los detalles que no están relacionados, como el marcado de un botón y el marcado de una barra lateral, están aislados entre sí, haciendo que sea más seguro cambiar cualquiera de ellos por su cuenta.

Cada componente de React es una funci√≥n de JavaScript que puede contener alg√ļn marcado que React muestra en el navegador. Los componentes de React usan una extensi√≥n de sintaxis llamada JSX para representar el marcado. JSX se parece mucho a HTML, pero es un poco m√°s estricto y puede mostrar informaci√≥n din√°mica. La mejor manera de comprender esto es convertir algunas marcas HTML en marcas JSX.

Nota

JSX y React son independientes. A menudo se usan en conjunto, pero se pueden usar de forma separada. JSX es una extensión de sintaxis, mientras React es una biblioteca de JavaScript.

Convirtiendo HTML a JSX

Supongamos que tienes algo de HTML (perfectamente v√°lido):

<h1>Hedy Lamarr's Todos</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
>
<ul>
<li>Invent new traffic lights
<li>Rehearse a movie scene
<li>Improve the spectrum technology
</ul>

Y quieres ponerlo en tu componente:

export default function TodoList() {
return (
// ???
)
}

Si lo copias y pegas tal como est√°, no funcionar√°:

export default function TodoList() {
  return (
    // This doesn't quite work!
    <h1>Hedy Lamarr's Todos</h1>
    <img 
      src="https://i.imgur.com/yXOvdOSs.jpg" 
      alt="Hedy Lamarr" 
      class="photo"
    >
    <ul>
      <li>Invent new traffic lights
      <li>Rehearse a movie scene
      <li>Improve the spectrum technology
    </ul>

¡Esto se debe a que JSX es más estricto y tiene algunas restricciones más que HTML! Si lees los mensajes de error anteriores, te guiarán a corregir el marcado, o puedes seguir la guía a continuación.

Nota

La mayoría de las veces, los mensajes de error en pantalla de React te ayudarán a encontrar donde está el problema. ¡Dales una lectura si te quedas atascado!.

Las Reglas de JSX

1. Devolver un solo elemento raíz

Para devolver m√ļltiples elementos de un componente, envu√©lvelos con una sola etiqueta principal.

Por ejemplo, puedes usar un <div>:

<div>
<h1>Hedy Lamarr's Todos</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
>
<ul>
...
</ul>
</div>

Si no deseas agregar un <div> adicional a tu marcado, puedes escribir <> y </> en su lugar:

<>
<h1>Hedy Lamarr's Todos</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
>
<ul>
...
</ul>
</>

Esta etiqueta vac√≠a se llama un Fragmento. Los Fragmentos te permiten agrupar cosas sin dejar ning√ļn rastro en el √°rbol HTML del navegador.

Deep Dive

¬ŅPor qu√© se necesita envolver m√ļltiples etiquetas JSX?

JSX parece HTML, pero por debajo se transforma en objetos planos de JavaScript. No puedes devolver dos objetos de una función sin envolverlos en un array. Esto explica por qué tampoco puedes devolver dos etiquetas JSX sin envolverlas en otra etiqueta o Fragmento.

2. Cierra todas las etiquetas

JSX requiere que las etiquetas se cierren explícitamente: las etiquetas de cierre automático como <img> deben convertirse en <img />, y etiquetas envolventes como <li>oranges deben convertirse como <li>oranges</li>.

Así es como la imagen y los elementos de la lista de Hedy Lamarr se ven cerrados:

<>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
/>
<ul>
<li>Invent new traffic lights</li>
<li>Rehearse a movie scene</li>
<li>Improve the spectrum technology</li>
</ul>
</>

3. ¡camelCase todo la mayoría de las cosas!

JSX se convierte en JavaScript y los atributos escritos en JSX se convierten en keys de objetos JavaScript. En tus propios componentes, a menudo vas a querer leer esos atributos en variables. Pero JavaScript tiene limitaciones en los nombres de variables. Por ejemplo, sus nombres no pueden contener guiones ni ser palabras reservadas como class.

Por eso, en React, muchos atributos HTML y SVG est√°n escritos en camelCase. Por ejemplo, en lugar de stroke-width usa strokeWidth. Dado que class es una palabra reservada, en React escribes className en su lugar, con el nombre de la propiedad DOM correspondiente:

<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
className="photo"
/>

Puedes encontrar todos estos atributos en React DOM Elements. Si te equivocas en uno, no te preocupes, React imprimirá un mensaje con una posible corrección en la consola del navegador.

Atención

Por razones históricas, los atributos aria-* y data-* se escriben como en HTML, con guiones.

Consejo profesional: usa un convertidor JSX

¬°Convertir todos estos atributos en marcas existentes puede ser tedioso! Recomendamos usar un convertidor para traducir su HTML y SVG existente a JSX. Los convertidores son muy √ļtiles en la pr√°ctica, pero aun as√≠ vale la pena entender lo que sucede as√≠ puedes escribir JSX c√≥modamente por tu cuenta.

Aquí está tu resultado final:

export default function TodoList() {
  return (
    <>
      <h1>Hedy Lamarr's Todos</h1>
      <img 
        src="https://i.imgur.com/yXOvdOSs.jpg" 
        alt="Hedy Lamarr" 
        className="photo" 
      />
      <ul>
        <li>Invent new traffic lights</li>
        <li>Rehearse a movie scene</li>
        <li>Improve the spectrum technology</li>
      </ul>
    </>
  );
}

Recapitulación

Ahora sabes por qué existe JSX y cómo usarlo en componentes:

  • Los componentes de React agrupan la l√≥gica de renderizaci√≥n junto con el marcado porque est√°n relacionados.
  • JSX es similar a HTML, con algunas diferencias. Puede usar un convertidor si lo necesita.
  • Los mensajes de error a menudo te guiar√°n en la direcci√≥n correcta para corregir tu marcado.

Desafío 1 de 1:
Convierte algo de HTML a JSX

Este HTML se pegó en un componente, pero no es JSX válido. Arreglalo;

export default function Bio() {
  return (
    <div class="intro">
      <h1>Welcome to my website!</h1>
    </div>
    <p class="summary">
      You can find my thoughts here.
      <br><br>
      <b>And <i>pictures</b></i> of scientists!
    </p>
  );
}

¬°T√ļ decides si hacerlo a mano o usando el convertidor!