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.
javascript1function Boton({ label = "Enviar", onClick }) { 2 return <button onClick={onClick}>{label}</button>; 3}
javascript1function 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
childrenpermite 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).
javascript1function 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}
javascript1function 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
...propspermite reenviar props a un elemento o componente hijo.- Usalo con cuidado para no propagar props invalidas al DOM.
- Componentes controlados reciben
valueyonChangedesde el padre.
javascript1function Input({ label, ...inputProps }) { 2 return ( 3 <label> 4 {label} 5 <input {...inputProps} /> 6 </label> 7 ); 8}
javascript1function 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
1function Perfil({ nombre, edad }) {
2 return (
3 <div>
4 <h2>{nombre}</h2>
5 <p>{edad}</p>
6 </div>
7 );
8}Children prop
1function Card({ children }) {
2 return <div className="card">{children}</div>;
3}Validación con PropTypes
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áctica guiada - Componentes reutilizables
Práctica
Crear Header, Footer y Button reutilizable con props y estilos.
Desafío de Código
Ejercicios - Props
Ejercicios
(1) Tarjeta de usuario, (2) lista de productos, (3) componente Input con spread props.
Documentación Oficial
Reto de Lectura
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.
jsx1function 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:
- Clasifica los 5 componentes: ¿quién USA
usuarioy quién solo lo TRANSPORTA? - ¿Qué componentes hay que tocar si mañana
PerfilBadgetambién necesita el email? Ese es el costo real del drilling. - Rediseña usando composición (la prop
children): los intermediarios no deben saber queusuarioexiste. No uses Context — la próxima semana lo vemos y compararás. - ¿En qué momento el drilling deja de ser un problema aceptable y amerita Context? Da un criterio, no un número mágico.
La solución no se publica. Se revisa en voz alta en el laboratorio, después de que trabajaste el reto. Trae tu diagnóstico escrito: eso es lo que se entrega.
Clase 18 de 33 en la ruta Desarrollo web