learning-front

Nivel 6 · React de cero a héroe (con TypeScript)

Qué es React y tu primera app

Por qué React y el salto del DOM imperativo al declarativo; qué es un componente, qué es un .tsx y cómo una app llega a la pantalla con createRoot.

Llevas tres niveles construyendo el Team Builder. En el Nivel 2 ya hacías que la página cambiara sola con JavaScript: buscabas un elemento, le cambiabas el texto, creabas nodos. Funciona, pero en cuanto la interfaz crece —y un equipo de héroes con filtros, búsqueda y un marcador crece rápido— ese trabajo manual se vuelve frágil. React existe para quitarte ese peso de encima. Este capítulo no entra todavía en todo lo que React sabe hacer: solo responde tres preguntas —qué es, por qué, y cómo arranca— y te pone tu primer componente en la pantalla.

Del Nivel 2 a React: dar pasos vs describir el resultado#

Así actualizabas la página en el Nivel 2. Tú dabas las órdenes, una a una:

javascript
// Buscas el elemento en el DOM, igual que aprendiste en el Nivel 2.
const titulo = document.querySelector("h1");
// Y le cambias el contenido tú mismo, a mano.
titulo.textContent = "Team Builder";

Esto es código imperativo: una lista de pasos para modificar el DOM. Con un título da igual, pero imagina mantener a mano cada cambio de una lista de héroes que se filtra y se reordena. Tendrías que acordarte de qué tocar, cuándo y en qué orden. Ahí es donde se rompen las cosas.

React le da la vuelta. En vez de dar pasos, describes cómo quieres que se vea la pantalla para unos datos dados, y React se encarga de tocar el DOM por ti: calcula qué ha cambiado y aplica solo eso. A esto se le llama enfoque declarativo. Tú dices qué quieres ver; React resuelve el cómo.

Qué es un componente#

La pieza con la que describes la interfaz en React es el componente. Y un componente, por debajo, no es nada exótico: es una función que devuelve la descripción de lo que se ve.

tsx
// Un componente es una función. Su nombre empieza por MAYÚSCULA (App, no app):
// así React lo distingue de una etiqueta HTML normal.
function App() {
  // Lo que va en el return describe lo que se verá en la pantalla.
  // Esto es JSX: se parece a HTML, pero está escrito dentro de TypeScript.
  return <h1>Team Builder</h1>;
}

Eso de <h1>Team Builder</h1> escrito en medio del código se llama JSX. Por ahora quédate con la idea: es la forma de describir interfaz dentro de una función, y se parece al HTML que ya conoces a propósito. En el próximo capítulo lo verás a fondo (atributos, expresiones, cómo combinar componentes). Aquí solo necesitas saber que un componente es una función que devuelve JSX.

La mayúscula no es un capricho de estilo: React la usa para diferenciar tus componentes (<App />) de las etiquetas del navegador (<h1>, <section>). Si llamas a tu componente app y escribes <app />, React no busca tu función: cree que es una etiqueta HTML llamada app, que el navegador no conoce, así que pinta un elemento vacío y tu componente no aparece —sin error, sin pista—. Por eso: componentes siempre en mayúscula.

Por qué .tsx y no .jsx#

Vienes del Nivel 5, así que ya no escribes JavaScript a secas: escribes TypeScript, con sus tipos. React encaja con eso sin fricción. El JSX que acabas de ver se escribe dentro de un fichero .tsx: la t es de TypeScript, y la x es de ese JSX. Es decir, JSX dentro de TypeScript, los dos en el mismo fichero.

Hay también ficheros .jsx (JSX dentro de JavaScript, sin tipos), pero en este curso todo React se escribe en .tsx, tipado desde el primer día. No es un extra para más adelante: es cómo se trabaja en empresa, y te da los mismos avisos del compilador que ya valoraste en el Nivel 5, ahora también sobre tu interfaz.

Cómo arranca: del fichero a la pantalla#

Un componente, por sí solo, no aparece en ningún sitio: es solo una función. Falta el paso que lo monta en la página de verdad. Ese paso vive, por convención, en un fichero llamado main.tsx, y lo da una función de React: createRoot.

Primero, en el HTML de la página hay un contenedor vacío que sirve de punto de anclaje:

html
<!-- Un único div vacío. React montará tu app aquí dentro. -->
<div id="root"></div>

Y en main.tsx enganchas tu componente a ese contenedor:

tsx
// react-dom es la parte de React que habla con el DOM del navegador.
// De ahí sacamos createRoot.
import { createRoot } from "react-dom/client";

// Nuestro componente, como antes.
function App() {
  return <h1>Team Builder</h1>;
}

// Buscamos el contenedor en el DOM, igual que en el Nivel 2.
// Ojo: getElementById devuelve el elemento... o null si no lo encuentra.
const contenedor = document.getElementById("root");

Aquí aparece un detalle de TypeScript que ya conoces del Nivel 5: getElementById devuelve HTMLElement | null, porque podría no encontrar el nodo. Si intentas montar sobre algo que quizá es null, el compilador protesta, y con razón. Tienes dos formas de resolverlo.

La rápida es el operador !, que le asegura a TypeScript que ese valor no es null:

tsx
// El "!" significa: "este valor no es null, confía en mí".
// Lo usamos porque sabemos que <div id="root"> está en el HTML.
const contenedor = document.getElementById("root")!;

// createRoot crea la raíz de React sobre ese nodo...
// ...y render() pinta nuestro componente dentro.
createRoot(contenedor).render(<App />);

El ! es cómodo, pero es una promesa: si te equivocas y el nodo no está, la app revienta en ejecución. Más adelante, en el ejercicio, verás la alternativa más robusta —comprobar el nodo en vez de prometer que existe—, que es la que prefiere el código de calidad. Por ahora, con esto ya tienes una app de React montándose en la pantalla.

Pruébalo#

Este es el arranque completo en un solo fichero: un componente y su montaje. Cámbiale el texto del <h1> y pulsa Ejecutar para verlo reflejado.

Comprueba lo que sabes#

Pregunta 1 de 4

¿Qué es un componente de React?

Tu turno#

Ejercicio · en esta página

Tu primer componente, en la pantalla

Escribe un componente App que devuelva un <h1> con "Team Builder" y móntalo en el contenedor #root con createRoot. Cuando ejecutes, debe verse renderizado.

Paso 1: Renderiza

  • App es una función que empieza por mayúscula y devuelve JSX
  • Se monta con createRoot(contenedor).render(<App />) sobre #root
  • Al ejecutar, se ve el componente en la pantalla
Ver soluciones
// createRoot monta el árbol de React dentro de un nodo del DOM.
import { createRoot } from "react-dom/client";

// Un componente: una función que empieza por mayúscula y devuelve JSX.
function App() {
  // El return describe lo que se ve. Es JSX: parece HTML, pero vive en TypeScript.
  return <h1>Team Builder</h1>;
}

// Cogemos el contenedor que la página deja preparado para montar la app.
// getElementById puede devolver null; con "!" le aseguramos a TS que existe.
const contenedor = document.getElementById("root")!;

// createRoot crea la raíz de React en ese nodo; render pinta el componente dentro.
createRoot(contenedor).render(<App />);

Por qué este nivel

  • Lo mínimo que funciona: un componente que devuelve un <h1> y se monta con createRoot. Renderiza, que es el objetivo del capítulo.