Props y Composición de Componentes
Volver a clases
Principiante

Props y Composición de Componentes

120 min

Pasar datos con props, validar con PropTypes y componer UI con children.

Props en profundidad

  • Props son los datos que un componente recibe del padre.
  • Se pueden destructurar y usar valores por defecto para evitar errores.
  • Se pueden pasar funciones para callbacks y manejar eventos.
  • Inmutables: un componente no debe modificar sus props; si necesita cambiar datos, debe pedirle al padre con un callback.
  • Datos derivados: si una prop se puede calcular desde otras, no la dupliques en el hijo (evita inconsistencias).
  • Prop drilling: pasar props por muchos niveles puede complicar el codigo; es una senal para reorganizar componentes.
javascript
1function Boton({ label = "Enviar", onClick }) {
2  return <button onClick={onClick}>{label}</button>;
3}
javascript
1function Lista({ items, onSelect }) {
2  return (
3    <ul>
4      {items.map((item) => (
5        <li key={item.id} onClick={() => onSelect(item)}>
6          {item.nombre}
7        </li>
8      ))}
9    </ul>
10  );
11}

PropTypes

  • Validación en desarrollo para asegurar tipos correctos.
  • Útil cuando se trabaja en equipo o con componentes reutilizables.
  • Ayuda a detectar errores de integracion al pasar props incorrectas.
  • En proyectos TypeScript suele reemplazarse por tipos, pero sigue siendo util en JS puro.

Children y composición

  • children permite componer componentes reutilizables (Card, Layout, Modal).
  • Favorece una UI flexible sin repetir lógica.
  • Patrón "slot": agregar secciones opcionales dentro de un componente.
  • Patrón "container": separa layout (contenedor) de contenido (children).
javascript
1function Card({ title, children, footer }) {
2  return (
3    <section className="card">
4      <h3>{title}</h3>
5      <div className="card-body">{children}</div>
6      {footer && <div className="card-footer">{footer}</div>}
7    </section>
8  );
9}
javascript
1function Layout({ children }) {
2  return (
3    <div className="layout">
4      <header>Mi App</header>
5      <main>{children}</main>
6    </div>
7  );
8}

Spread props y componentes controlados

  • ...props permite reenviar props a un elemento o componente hijo.
  • Usalo con cuidado para no propagar props invalidas al DOM.
  • Componentes controlados reciben value y onChange desde el padre.
javascript
1function Input({ label, ...inputProps }) {
2  return (
3    <label>
4      {label}
5      <input {...inputProps} />
6    </label>
7  );
8}
javascript
1function Formulario() {
2  const [email, setEmail] = useState("");
3  return (
4    <Input
5      label="Email"
6      value={email}
7      onChange={(e) => setEmail(e.target.value)}
8    />
9  );
10}

Ejemplos de Código

3 ejemplos

Props destructuradas

javascript
1function Perfil({ nombre, edad }) {
2  return (
3    <div>
4      <h2>{nombre}</h2>
5      <p>{edad}</p>
6    </div>
7  );
8}

Children prop

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

Validación con PropTypes

javascript
1import PropTypes from "prop-types";
2
3Usuario.propTypes = {
4  nombre: PropTypes.string.isRequired,
5  edad: PropTypes.number,
6};

Recursos

4 recursos disponibles

¡Hora de Practicar!

PrácticaPrincipiante15 min🟡 IA con bitácora

Práctica guiada - Componentes reutilizables

Práctica

Crear Header, Footer y Button reutilizable con props y estilos.

Desafío de Código

EjercicioPrincipiante15 min🔴 Sin IA

Ejercicios - Props

Ejercicios

(1) Tarjeta de usuario, (2) lista de productos, (3) componente Input con spread props.

Documentación Oficial

DocumentaciónPrincipiante15 min

React Props

Guía oficial para props y composición.

Reto de Lectura

Reto de LecturaPrincipiante35 min🔴 Sin IA

Reto de Lectura — El prop drilling infernal

Un dato viaja por 4 componentes que no lo usan para llegar al quinto que sí. Identifica quién usa qué, y rediseña con composición.

Este árbol de componentes funciona, pero mantenerlo es una tortura: cambiar una prop obliga a tocar 4 archivos. Primero diagnostica, luego rediseña.

jsx
1function App() {
2  const usuario = { nombre: "Ana", avatar: "/ana.png", plan: "pro" };
3  return <Layout usuario={usuario} />;
4}
5
6function Layout({ usuario }) {
7  return (
8    <div className="layout">
9      <Header usuario={usuario} />
10      <main>Contenido principal...</main>
11    </div>
12  );
13}
14
15function Header({ usuario }) {
16  return (
17    <header>
18      <h1>Mi App</h1>
19      <Toolbar usuario={usuario} />
20    </header>
21  );
22}
23
24function Toolbar({ usuario }) {
25  return (
26    <nav>
27      <button>Inicio</button>
28      <PerfilBadge usuario={usuario} />
29    </nav>
30  );
31}
32
33function PerfilBadge({ usuario }) {
34  return (
35    <span className="badge">
36      <img src={usuario.avatar} alt={usuario.nombre} />
37      {usuario.nombre} ({usuario.plan})
38    </span>
39  );
40}

Tareas:

  1. Clasifica los 5 componentes: ¿quién USA usuario y quién solo lo TRANSPORTA?
  2. ¿Qué componentes hay que tocar si mañana PerfilBadge también necesita el email? Ese es el costo real del drilling.
  3. Rediseña usando composición (la prop children): los intermediarios no deben saber que usuario existe. No uses Context — la próxima semana lo vemos y compararás.
  4. ¿En qué momento el drilling deja de ser un problema aceptable y amerita Context? Da un criterio, no un número mágico.