Describir la UI

React es una biblioteca de JavaScript para renderizar interfaces de usuario (UI por sus siglas en inglés). La UI se construye a partir de pequeñas unidades como botones, texto e imágenes. React te permite combinarlas en componentes reutilizables y anidables. Desde sitios web hasta aplicaciones de teléfonos, todo en la pantalla se puede descomponer en componentes. En este capítulo aprenderás a crear, adaptar y mostrar de forma condicional componentes de React.

Tu primer componente

Las aplicaciones de React se construyen a partir de piezas independientes de UI llamadas componentes. Un componente de React es una función de JavaScript a la que le puedes agregar un poco de marcado (markup). Los componentes pueden ser tan pequeños como un botón, o tan grandes como una página entera. Aquí vemos un componente Gallery que renderiza tres components Profile:

function Profile() {
return (
<img
src="https://i.imgur.com/MK3eW3As.jpg"
alt="Katherine Johnson"
/>
);
}

export default function Gallery() {
return (
<section>
<h1>Científicos increíbles</h1>
<Profile />
<Profile />
<Profile />
</section>
);
}

Error

Extra 185 of 186 byte(s) found at buffer[1]

¿Listo para aprender este tema?

Lee Tu primer componente para que aprendas cómo declarar y utilizar componentes de React.

Lee más

Importar y exportar componentes

Es posible declarar muchos componentes en un archivo, pero los archivos grandes pueden resultar difíciles de navegar. Como solución, puedes exportar un componente a su propio archivo, y luego importar ese componente desde otro archivo:

import Profile from './Profile.js';

export default function Gallery() {
  return (
    <section>
      <h1>Científicos increíbles</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}

¿Listo para aprender este tema?

Lee Importar y exportar componentes para que aprendas como dividir componentes en archivos propios.

Lee más

Escribir marcado con JSX

Cada componente de React es una función de JavaScript que puede contener algo de marcado que React renderiza en el navegador. Los componentes de React utilizan una sintaxis extendida que se llama JSX para representar ese marcado. JSX se parece muchísimo a HTML, pero es un poco más estricto y puede mostrar información dinámica.

Si pegamos marcado existente HTML en un componente de React, no funcionará siempre:

export default function TodoList() {
  return (
    // ¡Esto no funciona!
    <h1>Tareas Pendientes de Hedy Lamarr</h1>
    <img
      src="https://i.imgur.com/yXOvdOSs.jpg"
      alt="Hedy Lamarr"
      class="photo"
    >
    <ul>
      <li>Inventar nuevo semáforo
      <li>Ensayar la escena de la película
      <li>Mejorar la tecnología del espectro
    </ul>

Si tienes HTML existente como este, puedes arreglarlo usando un convertidor:

export default function TodoList() {
  return (
    <>
      <h1>Tareas Pendientes de Hedy Lamarr</h1>
      <img
        src="https://i.imgur.com/yXOvdOSs.jpg"
        alt="Hedy Lamarr"
        className="photo"
      />
      <ul>
        <li>Inventar nuevo semáforo</li>
        <li>Ensayar la escena de la película</li>
        <li>Mejorar la tecnología del espectro</li>
      </ul>
    </>
  );
}

¿Listo para aprender este tema?

Lee Escribir marcado con JSX para aprender cómo escribir JSX válido.

Lee más

JavaScript en JSX con llaves

JSX te permite escribir marcado similar a HTML dentro de un archivo JavaScript, manteniendo la lógica de renderizado y el contenido en el mismo lugar. En ocasiones será deseable añadir un poco de lógica en JavaScript o referenciar una propiedad dinámica dentro del marcado. En esta situación, puedes utilizar llaves en tu JSX para «abrir una ventana» hacia JavaScript:

const person = {
  name: 'Gregorio Y. Zara',
  theme: {
    backgroundColor: 'black',
    color: 'pink'
  }
};

export default function TodoList() {
  return (
    <div style={person.theme}>
      <h1>Tareas Pendientes de {person.name}</h1>
      <img
        className="avatar"
        src="https://i.imgur.com/7vQD0fPs.jpg"
        alt="Gregorio Y. Zara"
      />
      <ul>
        <li>Mejorar el videoteléfono</li>
        <li>Preparar clases de aeronáutica</li>
        <li>Trabajar en el motor de alcohol</li>
      </ul>
    </div>
  );
}

¿Listo para aprender este tema?

Lee JavaScript en JSX con llaves para aprender cómo acceder a JavaScript desde JSX.

Lee más

Pasar props a un componente

Los componentes de React utilizan props para comunicarse entre ellos. Cada componente padre puede pasar alguna información a sus componentes hijos dándoles props. Las props pueden recodarte a los atributos de HTML, pero puedes pasar cualquier valor de JavaScript con ellas, incluyendo objetos, arreglos, funciones, ¡e incluso JSX!

import { getImageUrl } from './utils.js'

export default function Profile() {
  return (
    <Card>
      <Avatar
        size={100}
        person={{
          name: 'Katsuko Saruhashi',
          imageId: 'YfeOqp2'
        }}
      />
    </Card>
  );
}

function Avatar({ person, size }) {
  return (
    <img
      className="avatar"
      src={getImageUrl(person)}
      alt={person.name}
      width={size}
      height={size}
    />
  );
}

function Card({ children }) {
  return (
    <div className="card">
      {children}
    </div>
  );
}

¿Listo para aprender este tema?

Lee Pasar props a un componente para aprender cómo pasar y leer props.

Lee más

Renderizado condicional

Tus componentes a menudo necesitarán mostrar algo distinto en diferentes condiciones. En React, puedes renderizar JSX de forma condicional usando sintaxis de JavaScript como las sentencias if, y los operadores && y ? :.

En este ejemplo, el operador && se utiliza para renderizar condicionalmente una marca:

function Item({ name, isPacked }) {
  return (
    <li className="item">
      {name} {isPacked && '✅'}
    </li>
  );
}

export default function PackingList() {
  return (
    <section>
      <h1>Lista de equipaje de Sally Ride</h1>
      <ul>
        <Item
          isPacked={true}
          name="Traje de vuelo"
        />
        <Item
          isPacked={true}
          name="Casco con dorado a la hoja"
        />
        <Item
          isPacked={false}
          name="Fotografía de Tam"
        />
      </ul>
    </section>
  );
}

¿Listo para aprender este tema?

Lee Renderizado condicional para aprender las diferentes formas de renderizar contenido condicionalmente.

Lee más

Renderizado de listas

A menudo querrás mostrar múltiples componentes similares a partir de una colección de datos. Puedes utilizar filter() y map() de JavaScript junto con React para filtrar y transformar tus arreglos de datos en un arreglo de componentes.

Para cada elemento del arreglo, deberás especificar una prop key. Usualmente, querrás usar un ID de la base de datos como key. Las key le permiten a React seguir el lugar de cada elemento en la lista aún cuando la lista cambie.

import { people } from './data.js';
import { getImageUrl } from './utils.js';

export default function List() {
  const listItems = people.map(person =>
    <li key={person.id}>
      <img
        src={getImageUrl(person)}
        alt={person.name}
      />
      <p>
        <b>{person.name}:</b>
        {' ' + person.profession + ' '}
        conocido/a por {person.accomplishment}
      </p>
    </li>
  );
  return (
    <article>
      <h1>Científicos</h1>
      <ul>{listItems}</ul>
    </article>
  );
}

¿Listo para aprender este tema?

Lee Renderizado de listas para aprender cómo renderizar una lista de componentes, y cómo elegir una key.

Lee más

Mantener los componentes puros

Algunas funciones de JavaScript son puras. Una función pura:

  • Se ocupa de sus propios asuntos. No cambia ningún objeto o variable que haya existido antes de ser llamada.
  • Misma entrada, misma salida. Dada la misma entrada, una función pura debería devolver siempre el mismo resultado.

Si de forma estricta solo escribes tus componentes como funciones puras, puedes evitar toda una clase de errores desconcertantes y comportamientos impredecibles a medida que tu base de código crece. Aquí hay un ejemplo de un componente impuro:

let guest = 0;

function Cup() {
  // Mal: ¡cambiar una variable preexistente!
  guest = guest + 1;
  return <h2>Taza de té para invitado #{guest}</h2>;
}

export default function TeaSet() {
  return (
    <>
      <Cup />
      <Cup />
      <Cup />
    </>
  );
}

Puedes hacer este componente puro pasando una prop en lugar de modificar una variable ya existente:

function Cup({ guest }) {
  return <h2>Taza de té para invitado #{guest}</h2>;
}

export default function TeaSet() {
  return (
    <>
      <Cup guest={1} />
      <Cup guest={2} />
      <Cup guest={3} />
    </>
  );
}

¿Listo para aprender este tema?

Lee Mantener los componentes puros para aprender a escribir componentes como funciones puras y predecibles.

Lee más

Tu UI como un árbol

React utiliza árboles para modelar las relaciones entre componentes y módulos.

Un árbol de renderizado de React es una representación de la relación padre-hijo entre componentes.

Un gráfo de árbol con cinco nodos, con cada nodo que representa un componente. El nodo raíz se localiza en la cima del grafo de árbol y está etiquetado como 'Root Component'. Tiene dos flechas que se extienden hacia abajo a dos nodos etiquetados como 'Component A' y 'Component C'. Cada una de las flechas está etiquetada con 'renders'. El 'Component A' tiene una sola flecha 'renders' hacia un nodo etiquetado como 'Component B'. 'Component C' tiene una sola flecha 'renders' hacia un nodo etiquetado como 'Component D'.
Un gráfo de árbol con cinco nodos, con cada nodo que representa un componente. El nodo raíz se localiza en la cima del grafo de árbol y está etiquetado como 'Root Component'. Tiene dos flechas que se extienden hacia abajo a dos nodos etiquetados como 'Component A' y 'Component C'. Cada una de las flechas está etiquetada con 'renders'. El 'Component A' tiene una sola flecha 'renders' hacia un nodo etiquetado como 'Component B'. 'Component C' tiene una sola flecha 'renders' hacia un nodo etiquetado como 'Component D'.

Un ejemplo de un árbol de renderizado de React.

Los componentes cercanos a la cima del árbol, cerca del componente raíz, se consideran componentes de nivel superior. Los componentes sin componentes hijos son componentes hoja. Esta categorización de los componentes es útil para entender el flujo de datos y el rendimiento del renderizado.

Modelar la relación entre los módulos de JavaScript es otra forma útil de entender tu apliación. Nos referimos a esto como un árbol de dependencia de módulos.

Un grafo de árbol con cinco nodos. Cada nodo representa un módulo de JavaScript. El nodo superior está etiquetado como 'RootModule.js'. Tiene tres flechas que se extienden hacia los nodos: 'ModuleA.js', 'ModuleB.js' y 'ModuleC.js'. Cada flecha se etiqueta como 'imports'. El nodo 'ModuleC.js' tiene una sola flecha 'imports' que apunta al nodo etiquetado como 'ModuleD.js'.
Un grafo de árbol con cinco nodos. Cada nodo representa un módulo de JavaScript. El nodo superior está etiquetado como 'RootModule.js'. Tiene tres flechas que se extienden hacia los nodos: 'ModuleA.js', 'ModuleB.js' y 'ModuleC.js'. Cada flecha se etiqueta como 'imports'. El nodo 'ModuleC.js' tiene una sola flecha 'imports' que apunta al nodo etiquetado como 'ModuleD.js'.

Un ejemplo de un árbol de dependecias de módulos.

Un árbol de dependencias se usa a menudo para construir herramientas que empaquetan todo el código relevante de JavaScript para que el cliente descargue y renderice. Un tamaño grande del paquete significa una regresión en la experiencia de usuario para las aplicaciones de React. Entender el árbol de dependencias de los móduls ayuda a depurar tales problemas.

¿Listo para aprender este tema?

Lee Tu UI como un árbol para aprender como crear árboles de renderizado y dependencias para una aplicación de React y cómo son modelos mentales útiles para mejorar la experiencia de usuario y el rendimiento.

Lee más

¿Qué sigue?

¡Dirígete a Tu primer componente para que comiences a leer este capítulo página por página!

O, si ya te resultan familiares estos temas, ¿por qué no leer sobre cómo Agregar interactividad?