21. Props para objetos
Tutorial de Props para Objetos en React
Introducción a las Props en React
Las props (abreviatura de propiedades) son la forma principal de pasar datos de un componente padre a un componente hijo en React. Cuando necesitas pasar múltiples valores relacionados, usar objetos como props puede ser más eficiente y organizado.
Tabla de Contenidos
Props Básicas vs Props como Objetos
Pasando Objetos como Props
Desestructuración de Props Objeto
Props con Valores por Defecto
Validación de Props con PropTypes
Props Objeto con TypeScript
Mejores Prácticas
1. Props Básicas vs Props como Objetos
Ejemplo con props individuales:
jsx
// Componente hijo
function UsuarioIndividual(props) {
return (
<div className="usuario">
<h3>{props.nombre}</h3>
<p>Edad: {props.edad}</p>
<p>Email: {props.email}</p>
<p>Rol: {props.rol}</p>
</div>
);
}
// Componente padre
function App() {
return (
<UsuarioIndividual
nombre="Ana García"
edad={28}
email="ana@email.com"
rol="Desarrolladora"
/>
);
}
Ejemplo con objeto como prop:
jsx
// Componente hijo
function UsuarioConObjeto(props) {
return (
<div className="usuario">
<h3>{props.usuario.nombre}</h3>
<p>Edad: {props.usuario.edad}</p>
<p>Email: {props.usuario.email}</p>
<p>Rol: {props.usuario.rol}</p>
</div>
);
}
// Componente padre
function App() {
const usuario = {
nombre: "Ana García",
edad: 28,
email: "ana@email.com",
rol: "Desarrolladora"
};
return <UsuarioConObjeto usuario={usuario} />;
}
2. Pasando Objetos como Props-Ejemplo completo:
// ProductoCard.jsx - Componente hijo
function ProductoCard(props) {
const { producto } = props;
return (
<div className="card producto-card">
<img src={producto.imagen} alt={producto.nombre} />
<div className="card-content">
<h3>{producto.nombre}</h3>
<p>{producto.descripcion}</p>
<div className="producto-info">
<span className="precio">${producto.precio}</span>
<span className={`stock ${producto.stock > 0 ? 'disponible' : 'agotado'}`}>
{producto.stock > 0 ? `${producto.stock} disponibles` : 'Agotado'}
</span>
</div>
<button
className="btn-comprar"
disabled={producto.stock === 0}
>
{producto.stock > 0 ? 'Añadir al carrito' : 'No disponible'}
</button>
</div>
</div>
);
}// App.jsx - Componente padre
function App() {
const productoEjemplo = {
id: 1,
nombre: "Laptop Gaming Pro",
descripcion: "Laptop de alto rendimiento para gaming y trabajo",
precio: 1299.99,
stock: 15,
imagen: "https://images.unsplash.com/photo-1603302576837-37561b2e2302",
categoria: "Electrónicos",
rating: 4.5,
especificaciones: {
procesador: "Intel i7",
ram: "16GB",
almacenamiento: "1TB SSD"
} };
return (
<div className="App">
<h1>Tienda Online</h1>
<ProductoCard producto={productoEjemplo} />
</div>
);
}
3. Desestructuración de Props Objeto
La desestructuración hace el código más limpio y legible:
jsx
// Opción 1: Desestructuración en los parámetros
function ProductoCard({ producto }) {
// Ahora podemos usar 'producto' directamente
return (
<div className="card">
<h3>{producto.nombre}</h3>
{/* ... resto del componente */}
</div>
);
}
// Opción 2: Desestructuración anidada
function ProductoCard({
producto: {
nombre,
precio,
stock,
imagen,
especificaciones: { procesador, ram }
}
}) {
return (
<div className="card">
<h3>{nombre}</h3>
<p>Precio: ${precio}</p>
<p>Procesador: {procesador}</p>
<p>RAM: {ram}</p>
{/* ... resto del componente */}
</div>
);
}
// Opción 3: Desestructuración dentro del componente
function ProductoCard(props) {
const {
producto: {
nombre,
precio,
stock,
// Valores por defecto en desestructuración
rating = 0,
descripcion = "Sin descripción disponible"
}
} = props;
return (
<div className="card">
<h3>{nombre}</h3>
<p>{descripcion}</p>
<p>Precio: ${precio}</p>
<p>Rating: {"★".repeat(Math.floor(rating))}</p>
</div>
);
}
4. Props con Valores por Defecto
Para componentes funcionales:
jsx
function PerfilUsuario({ usuario = {} }) {
// Valores por defecto con desestructuración
const {
nombre = "Usuario Anónimo",
edad = 0,
email = "No proporcionado",
avatar = "https://via.placeholder.com/150",
activo = false
} = usuario;
return (
<div className={`perfil ${activo ? 'activo' : 'inactivo'}`}>
<img src={avatar} alt={nombre} />
<div className="info">
<h3>{nombre}</h3>
<p>Edad: {edad}</p>
<p>Email: {email}</p>
<span className="estado">
{activo ? '🟢 En línea' : '⚫ Desconectado'}
</span>
</div>
</div>
);
}
// O usando defaultProps
PerfilUsuario.defaultProps = {
usuario: {
nombre: "Usuario Anónimo",
edad: 0,
email: "No proporcionado",
avatar: "https://via.placeholder.com/150",
activo: false
}
};
5. Validación de Props con PropTypes
jsx
import PropTypes from 'prop-types';
function ProductoCard({ producto }) {
// Componente aquí...
}
ProductoCard.propTypes = {
producto: PropTypes.shape({
id: PropTypes.number.isRequired,
nombre: PropTypes.string.isRequired,
descripcion: PropTypes.string,
precio: PropTypes.number.isRequired,
stock: PropTypes.number,
imagen: PropTypes.string,
categoria: PropTypes.oneOf(['Electrónicos', 'Ropa', 'Hogar', 'Otros']),
rating: PropTypes.number,
especificaciones: PropTypes.shape({
procesador: PropTypes.string,
ram: PropTypes.string,
almacenamiento: PropTypes.string
}),
// Función como propiedad
onComprar: PropTypes.func
}).isRequired
};
ProductoCard.defaultProps = {
producto: {
stock: 0,
rating: 0,
categoria: 'Otros',
especificaciones: {}
}
};
6. Props Objeto con TypeScript
tsx
// Definición de tipos/interfaces
interface Especificaciones {
procesador: string;
ram: string;
almacenamiento: string;
pantalla?: string; // Opcional
}
interface Producto {
id: number;
nombre: string;
descripcion: string;
precio: number;
stock: number;
imagen: string;
categoria: 'Electrónicos' | 'Ropa' | 'Hogar' | 'Otros';
rating: number;
especificaciones: Especificaciones;
onAgregarCarrito?: () => void; // Función opcional
}
// Props del componente
interface ProductoCardProps {
producto: Producto;
destacado?: boolean;
className?: string;
}
// Componente con TypeScript
function ProductoCard({
producto,
destacado = false,
className = ''
}: ProductoCardProps): JSX.Element {
const {
nombre,
precio,
stock,
imagen,
especificaciones: { procesador, ram }
} = producto;
return (
<div className={`producto-card ${destacado ? 'destacado' : ''} ${className}`}>
{destacado && <span className="badge-destacado">🌟 Destacado</span>}
<img src={imagen} alt={nombre} />
<h3>{nombre}</h3>
<div className="especificaciones">
<p><strong>Procesador:</strong> {procesador}</p>
<p><strong>RAM:</strong> {ram}</p>
</div>
{/* ... resto del componente */}
</div>
);
}
7. Mejores Prácticas
1. Mantén los objetos de props simples
jsx
// ❌ Evita objetos demasiado complejos
<Componente
data={{
usuario: {
personal: { nombre, edad },
laboral: { empresa, puesto },
preferencias: { tema, idioma }
},
config: { /* ... */ }
}}
/>
// ✅ Separa en props más pequeñas
<Componente
usuario={usuario}
config={config}/>
2. Usa desestructuración consistentemente
jsx
// ✅ Más legible
function MiComponente({ usuario, config, onAction }) {
// Código limpio
}
// ❌ Menos legible
function MiComponente(props) {
const usuario = props.usuario;
const config = props.config;
// Más código...
}
3. Considera el rendimiento con objetos
jsx
// ❌ Esto crea un nuevo objeto en cada render
function App() {
return <Componente config={{ tema: 'oscuro', sonido: true }} />;
}
// ✅ Mejor: usa useMemo o define fuera del componente
function App() {
const config = useMemo(() => ({ tema: 'oscuro', sonido: true }), []);
return <Componente config={config} />;
}
4. Ejemplo completo aplicando buenas prácticas
jsx
// components/UserProfile.jsx
import PropTypes from 'prop-types';
function UserProfile({ user, onEdit, isEditable = false }) {
// Desestructuración con valores por defecto
const {
id,
name = 'Sin nombre',
email = 'No disponible',
avatar,
role = 'user',
preferences = {},
createdAt
} = user;
const { theme = 'light', notifications = true } = preferences;
// Formatear fecha
const joinDate = new Date(createdAt).toLocaleDateString();
return (
<div className={`user-profile theme-${theme}`}>
<div className="profile-header">
<img
src={avatar || 'https://via.placeholder.com/100'}
alt={name}
className="profile-avatar"
/>
<div className="profile-info">
<h2>{name}</h2>
<p className="email">{email}</p>
<span className={`role-badge role-${role}`}>
{role.toUpperCase()}
</span>
</div>
{isEditable && (
<button onClick={onEdit} className="edit-btn">
✏️ Editar
</button>
)}
</div>
<div className="profile-details">
<div className="detail-item">
<span className="detail-label">Miembro desde:</span>
<span className="detail-value">{joinDate}</span>
</div>
<div className="detail-item">
<span className="detail-label">Notificaciones:</span>
<span className="detail-value">
{notifications ? 'Activadas' : 'Desactivadas'}
</span>
</div>
</div>
</div>
);
}
// Validación de props
UserProfile.propTypes = {
user: PropTypes.shape({
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
name: PropTypes.string,
email: PropTypes.string,
avatar: PropTypes.string,
role: PropTypes.oneOf(['admin', 'user', 'moderator']),
preferences: PropTypes.shape({
theme: PropTypes.oneOf(['light', 'dark']),
notifications: PropTypes.bool
}),
createdAt: PropTypes.oneOfType([PropTypes.string, PropTypes.instanceOf(Date)])
}).isRequired,
onEdit: PropTypes.func,
isEditable: PropTypes.bool
};
UserProfile.defaultProps = {
isEditable: false,
user: {
preferences: {}
}
};
export default UserProfile;
Ejercicio Práctico
Intenta crear este componente aplicando lo aprendido:
jsx
// Crea un componente RecipeCard que reciba:
// - recipe: objeto con propiedades (title, ingredients[], prepTime, difficulty, tags[])
// - onSave: función opcional
// - isVegetarian: booleano (calculado a partir de ingredients)
// Ejemplo de uso:
const recipe = {
title: "Ensalada César",
ingredients: ["lechuga", "pollo", "queso parmesano", "crutones"],
prepTime: 20, // minutos
difficulty: "Fácil",
tags: ["ensalada", "rápido", "almuerzo"],
servings: 4
};
<RecipeCard recipe={recipe} onSave={handleSaveRecipe} />
Conclusión
Usar objetos como props en React te permite:
Agrupar datos relacionados lógicamente
Hacer el código más mantenible
Facilitar la validación de tipos
Mejorar la reutilización de componentes
Hacer las interfaces de componentes más claras
Recuerda que cada situación es diferente. Evalúa si usar un objeto como prop es la mejor opción basándote en la complejidad y relación de los datos que necesitas pasar.
¡Ahora estás listo para usar objetos como props de manera efectiva en tus proyectos de React
**********************************
Props para Objetos en React ☕
📋 Introducción
En React, los props no solo pueden ser valores simples (texto, números, booleanos), sino también objetos completos que contienen múltiples propiedades. Esto es especialmente útil cuando necesitas pasar datos estructurados a tus componentes.
🎯 Objetivos del Tutorial
Aprender a pasar objetos como props
Entender cómo acceder a propiedades anidadas dentro de objetos
Practicar con diferentes formas de recibir props
Utilizar desestructuración para simplificar el código
📁 Estructura del Proyecto
text
src/
├── components/
│ ├── Coffee.jsx
│ └── User.jsx
├── App.jsx
├── index.jsx
└── ...
🚀 Paso 1: Configuración del Proyecto
Primero, crea un nuevo proyecto de React o usa uno existente.
Archivo: src/App.jsx
jsx
import React from 'react';
import { User } from './components/User';
function App() {
return (
<div>
<h1>🌟 Tutorial: Props con Objetos en React</h1>
<User
nombre="Ana García"
edad={25}
direccion={{
calle: "Av. Principal 123",
ciudad: "Madrid",
pais: "España"
}}
/>
</div>
);
}
export default App;
🔧 Paso 2: Creando Nuestro Primer Componente
Archivo: src/components/User.jsx
jsx
// Versión 1: Usando props como objeto
export function User(props) {
return (
<div style={{ border: '1px solid #ccc', padding: '20px', margin: '10px' }}>
<h2>👤 Usuario: {props.nombre}</h2>
<p>📅 Edad: {props.edad} años</p>
<p>📍 Dirección: {props.direccion.calle}, {props.direccion.ciudad}</p>
</div>
);
}
📊 Paso 3: Usando Desestructuración
La desestructuración nos permite extraer valores de objetos de forma más concisa.
Archivo actualizado: src/components/User.jsx
jsx
// Versión 2: Desestructurando props
export function User({ nombre, edad, direccion }) {
return (
<div style={{
border: '1px solid #4CAF50',
padding: '20px',
margin: '10px',
borderRadius: '10px',
backgroundColor: '#f9f9f9'
}}>
<h2 style={{ color: '#4CAF50' }}>👤 {nombre}</h2>
<p>🎂 {edad} años</p>
<p>📍 {direccion.calle}, {direccion.ciudad}, {direccion.pais}</p>
</div> );}
🏗️ Paso 4: Desestructuración Anidada
Podemos desestructurar aún más para acceder directamente a las propiedades internas.
Archivo actualizado: src/components/User.jsx
jsx
// Versión 3: Desestructuración anidada
export function User({
nombre,
edad,
direccion: { calle, ciudad, pais }
}) {
return (
<div style={userCardStyle}>
<h2 style={{ color: '#2196F3' }}>👤 {nombre}</h2>
<p>🎂 <strong>{edad}</strong> años</p>
<div style={addressStyle}>
<p>🏠 <strong>Calle:</strong> {calle}</p>
<p>🏙️ <strong>Ciudad:</strong> {ciudad}</p>
<p>🌍 <strong>País:</strong> {pais}</p>
</div>
</div>
);
}
const userCardStyle = {
border: '2px solid #2196F3',
padding: '25px',
margin: '15px',
borderRadius: '12px',
backgroundColor: '#e3f2fd',
boxShadow: '0 4px 6px rgba(0,0,0,0.1)'
};
const addressStyle = {
backgroundColor: 'white',
padding: '15px',
borderRadius: '8px',
marginTop: '10px'
};
🔍 Paso 5: Múltiples Usuarios con Datos Complejos
Archivo actualizado: src/App.jsxjsx
import React from 'react';
import { User } from './components/User';
function App() {
const usuarios = [
{
id: 1,
nombre: "Carlos Rodríguez",
edad: 30,
profesion: "Ingeniero de Software",
direccion: {
calle: "Calle Mayor 45",
ciudad: "Barcelona",
pais: "España",
codigoPostal: "08001"
},
contactos: {
email: "carlos@email.com",
telefono: "+34 600 123 456"
}
},
{
id: 2,
nombre: "Laura Martínez",
edad: 28,
profesion: "Diseñadora UX",
direccion: {
calle: "Gran Vía 22",
ciudad: "Valencia",
pais: "España",
codigoPostal: "46001"
},
contactos: {
email: "laura@email.com",
telefono: "+34 600 987 654"
}
}
];
return (
<div style={appStyle}>
<header style={headerStyle}>
<h1>📚 Tutorial: Props para Objetos en React</h1>
<p>Aprende a trabajar con objetos como props</p>
</header>
<div style={contentStyle}>
<h2>👥 Lista de Usuarios</h2>
{usuarios.map(usuario => (
<User
key={usuario.id}
nombre={usuario.nombre}
edad={usuario.edad}
profesion={usuario.profesion}
direccion={usuario.direccion}
contactos={usuario.contactos}
/>
))}
</div>
</div>
);
}
const appStyle = {
fontFamily: 'Arial, sans-serif',
maxWidth: '800px',
margin: '0 auto',
padding: '20px'
};
const headerStyle = {
textAlign: 'center',
backgroundColor: '#6200ea',
color: 'white',
padding: '30px',
borderRadius: '10px',
marginBottom: '30px'
};
const contentStyle = {
backgroundColor: 'white',
padding: '20px',
borderRadius: '10px',
boxShadow: '0 2px 10px rgba(0,0,0,0.1)'
};
export default App;
🎨 Paso 6: Componente Mejorado con Todos los Datos
Archivo actualizado: src/components/User.jsx
jsx
export function User({
nombre,
edad,
profesion,
direccion: { calle, ciudad, pais, codigoPostal },
contactos: { email, telefono }
}) {
// Depuración: ver qué props llegan
console.log(`Renderizando usuario: ${nombre}`);
return (
<div style={userCardStyle}>
<div style={userHeaderStyle}>
<h2 style={{ margin: 0 }}>👤 {nombre}</h2>
<span style={ageBadgeStyle}>{edad} años</span>
</div>
<p style={professionStyle}>💼 {profesion}</p>
<div style={sectionStyle}>
<h3 style={sectionTitleStyle}>📍 Dirección</h3>
<p>🏠 {calle}</p>
<p>🏙️ {ciudad}, {codigoPostal}</p>
<p>🌍 {pais}</p>
</div>
<div style={sectionStyle}>
<h3 style={sectionTitleStyle}>📞 Contacto</h3>
<p>📧 {email}</p>
<p>📱 {telefono}</p>
</div>
</div>
);
}
const userCardStyle = {
border: '2px solid #6200ea',
padding: '25px',
margin: '20px 0',
borderRadius: '12px',
backgroundColor: '#f3e5f5',
boxShadow: '0 4px 8px rgba(98, 0, 234, 0.1)',
transition: 'transform 0.3s ease'
};
const userHeaderStyle = {
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: '15px',
paddingBottom: '15px',
borderBottom: '1px solid #ddd'
};
const ageBadgeStyle = {
backgroundColor: '#6200ea',
color: 'white',
padding: '5px 15px',
borderRadius: '20px',
fontWeight: 'bold'
};
const professionStyle = {
backgroundColor: '#e8eaf6',
padding: '10px',
borderRadius: '5px',
margin: '15px 0'
};
const sectionStyle = {
backgroundColor: 'white',
padding: '15px',
borderRadius: '8px',
margin: '10px 0'
};
const sectionTitleStyle = {
color: '#6200ea',
marginTop: '0',
borderBottom: '2px solid #6200ea',
paddingBottom: '5px'
};
☕ Paso 7: Ejemplo con Componente Coffee
Archivo: src/components/Coffee.jsx
jsx
export function Coffee({
nombre,
precio,
origen,
descripcion,
caracteristicas: { tipo, intensidad, notas, cantidad },
disponible
}) {
return (
<div style={{
border: `3px solid ${disponible ? '#4CAF50' : '#f44336'}`,
padding: '20px',
margin: '15px',
borderRadius: '10px',
backgroundColor: '#fff8e1',
opacity: disponible ? 1 : 0.7
}}>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<h2 style={{ color: '#6d4c41', margin: 0 }}>☕ {nombre}</h2>
<span style={{
backgroundColor: disponible ? '#4CAF50' : '#f44336',
color: 'white',
padding: '5px 10px',
borderRadius: '5px',
fontWeight: 'bold'
}}>
{disponible ? 'DISPONIBLE' : 'AGOTADO'}
</span>
</div>
<p style={{ color: '#6d4c41', fontSize: '1.2em' }}>
<strong>💰 Precio:</strong> ${precio}
</p>
<p>🌍 <strong>Origen:</strong> {origen}</p>
<p>📝 {descripcion}</p>
<div style={{ backgroundColor: '#ffecb3', padding: '15px', borderRadius: '8px', marginTop: '15px' }}>
<h3 style={{ color: '#5d4037', marginTop: 0 }}>⚡ Características:</h3>
<ul style={{ listStyle: 'none', padding: 0 }}>
<li>🎯 <strong>Tipo:</strong> {tipo}</li>
<li>🔥 <strong>Intensidad:</strong> {'★'.repeat(intensidad)}</li>
<li>👃 <strong>Notas:</strong> {notas.join(', ')}</li>
<li>📦 <strong>Cantidad:</strong> {cantidad} g</li>
</ul>
</div>
</div>
);
}
🧪 Paso 8: Usando el Componente Coffee
Archivo actualizado: src/App.jsx
jsx
import React from 'react';
import { User } from './components/User';
import { Coffee } from './components/Coffee';
function App() {
const usuarios = [/* ... mismos datos anteriores ... */];
const cafes = [
{
id: 1,
nombre: "Arabica Premium",
precio: 12.99,
origen: "Colombia",
descripcion: "Café suave con notas frutales y acidez balanceada",
caracteristicas: {
tipo: "Grano Entero",
intensidad: 3,
notas: ["Chocolate", "Nuez", "Caramelo"],
cantidad: 250
},
disponible: true
},
{
id: 2,
nombre: "Robusta Intenso",
precio: 9.99,
origen: "Vietnam",
descripcion: "Café fuerte con alto contenido de cafeína",
caracteristicas: {
tipo: "Molido",
intensidad: 5,
notas: ["Madera", "Tierra", "Especias"],
cantidad: 500
},
disponible: false
}
];
return (
<div style={appStyle}>
<header style={headerStyle}>
<h1>📚 Tutorial: Props para Objetos en React</h1>
<p>Aprende a trabajar con objetos como props</p>
</header>
<main style={mainStyle}>
<section style={sectionStyle}>
<h2 style={sectionTitleStyle}>👥 Lista de Usuarios</h2>
{usuarios.map(usuario => (
<User key={usuario.id} {...usuario} />
))}
</section>
<section style={sectionStyle}>
<h2 style={sectionTitleStyle}>☕ Nuestros Cafés</h2>
{cafes.map(cafe => (
<Coffee key={cafe.id} {...cafe} />
))}
</section>
</main>
<footer style={footerStyle}>
<p>🎓 Tutorial práctico de React - Props con Objetos</p>
</footer>
</div>
);
}
const mainStyle = {
display: 'grid',
gridTemplateColumns: '1fr 1fr',
gap: '30px',
margin: '30px 0'
};
const sectionStyle = {
backgroundColor: 'white',
padding: '25px',
borderRadius: '10px',
boxShadow: '0 2px 10px rgba(0,0,0,0.1)'
};
const sectionTitleStyle = {
color: '#6200ea',
borderBottom: '3px solid #6200ea',
paddingBottom: '10px'
};
const footerStyle = {
textAlign: 'center',
marginTop: '30px',
padding: '20px',
backgroundColor: '#f5f5f5',
borderRadius: '8px',
color: '#666'
};
// ... otros estilos igual que antes ...
⚠️ Buenas Prácticas y Errores Comunes
✅ Correcto
jsx
// Usar desestructuración cuando conocemos las props
function User({ nombre, edad, direccion }) {
return <p>{nombre} vive en {direccion.ciudad}</p>;
}
// Validar props opcionales
function User({ nombre, direccion = {} }) {
return <p>{nombre} - {direccion.ciudad || "Ciudad no especificada"}</p>;
}
❌ Incorrecto
jsx
// Acceder sin verificar si existe
function User(props) {
return <p>{props.direccion.ciudad}</p>; // Error si direccion es undefined
}
// Sintaxis incorrecta para objetos
<User direccion="{ calle: '...' }" /> // ❌ Esto pasa un string!
<User direccion={{ calle: '...' }} /> // ✅ Esto pasa un objeto
🏆 Desafío Final: Componente Libro
Crea un componente Book que muestre:
jsx
<Book
titulo="Cien años de soledad"
autor={{
nombre: "Gabriel García Márquez",
nacionalidad: "Colombiano",
premioNobel: true
}}
detalles={{
paginas: 417,
genero: "Realismo mágico",
isbn: "978-3-16-148410-0",
editorial: "Sudamericana"
}}
disponible={true}
calificacion={4.8}
/>
Requisitos:
Usa desestructuración anidada
Añade emojis apropiados
Muestra un indicador de disponibilidad
Muestra las estrellas de calificación
Incluye console.log para depuración
📚 Resumen de Conceptos Clave
🎓 Puntos Clave para Recordar
Objetos como props permiten agrupar datos relacionados
La desestructuración hace tu código más limpio y legible
Usa console.log(props) para depurar y entender qué datos recibes
El operador ?. es tu amigo para props opcionales
React Developer Tools te ayudan a inspeccionar props en tiempo real
🚀 Próximos Pasos
Practica creando componentes con diferentes estructuras de objetos
Experimenta con props anidados más complejos
Aprende sobre propTypes para validación de tipos
Explora el operador spread para pasar props: <User {...userData} />
¡Feliz codificación! 🎉 Recuerda que la práctica constante es clave para dominar React.
*************************************************************************************************
Tutorial: Props para Objetos en React (Imágenes 21)
Introducción a Props en React
En React, las props (propiedades) son la forma principal de pasar datos de componentes padres a componentes hijos. En este tutorial aprenderemos a pasar objetos completos como props y a acceder a sus propiedades.
Ejercicio 1: Componente Básico con Props
Código de las imágenes 1-3
Usuarios.jsx:
jsx
// Versión inicial - props como parámetros individuales
export function Usuarios({ nombre, edad }) {
return (
<h1>{nombre}, tiene {edad}</h1>
)
}
index.jsx:
jsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { Usuarios } from './components/Usuarios.jsx';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<Usuarios nombre="frank" edad={21} />
<Usuarios nombre="pedro" edad={21} />
<Usuarios nombre="frank2" />
<Usuarios nombre="frank3" />
</React.StrictMode>
);
Resultado esperado:
text
frank, tiene 21
pedro, tiene 21
frank2, tiene
frank3, tiene
Ejercicio 2: Usando Props como Objeto-Código de las imágenes 4-6
Usuarios.jsx (actualizado):
jsx
// Usando props como objeto
export function Usuarios(props) {
return (
<div>
<h1>{props.nombre}</h1>
<h1>{props.edad}</h1>
</div>
)
}
index.jsx (actualizado):
jsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { Usuarios } from './components/Usuarios.jsx';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<Usuarios
nombre="frank"
edad={21}
/>
</React.StrictMode>
);
Ejercicio 3: Pasando Objetos como Props
Código de las imágenes 7-9
index.jsx (con objeto complejo):
jsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { Usuarios } from './components/Usuarios.jsx';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<Usuarios
nombre="frank"
edad={21}
direccion={{
calle: "calle san martín",
ciudad: "Lima",
pais: "peru"
}}
/>
</React.StrictMode>
);
Usuarios.jsx (accediendo a objeto anidado):
jsx
export function Usuarios(props) {
// Para depurar, podemos ver qué recibimos
console.log(props);
return (
<div>
<h1>{props.nombre}</h1>
<h1>{props.edad} ❤️</h1>
<h1>{props.direccion.calle}</h1>
</div>
)}
Ejercicio Completo: Acceso a Propiedades Anidadas
Versión final con destructuring
Usuarios.jsx (versión optimizada):
jsx
export function Usuarios({ nombre, edad, direccion }) {
// Destructuring para acceder fácilmente a las props
return (
<div>
<h1>👤 {nombre}</h1>
<h1>🎂 Edad: {edad} años</h1>
<h1>📍 Dirección:</h1>
<ul>
<li>Calle: {direccion.calle}</li>
<li>Ciudad: {direccion.ciudad}</li>
<li>País: {direccion.pais}</li>
</ul>
</div>
)
}
Conceptos Clave Explicados
1. Props como Objeto
jsx
// Componente que recibe props como objeto
function Componente(props) {
return <div>{props.nombre}</div>
}
2. Destructuring de Props
jsx
// Forma más limpia - destructuring
function Componente({ nombre, edad }) {
return <div>{nombre} - {edad}</div>
}
3. Objetos Anidados en Props
jsx
// Pasar objeto complejo
<Componente
datos={{
personal: { nombre: "Juan", edad: 25 },
contacto: { email: "juan@email.com" }
}}
/>
// Acceder a propiedades anidadas
function Componente({ datos }) {
return (
<div>
<p>{datos.personal.nombre}</p>
<p>{datos.contacto.email}</p>
</div>
)
}
4. Depuración con console.log
jsx
function Componente(props) {
console.log("Props recibidas:", props);
console.log("Prop específica:", props.direccion);
return <div>...</div>
}
Buenas Prácticas
Usar destructuring cuando sea posible para mayor claridad
Validar props con PropTypes o TypeScript
Pasar objetos completos cuando haya datos relacionados
Evitar mutar props directamente
Ejercicio Práctico
Crea un componente Perfil que reciba:
Un objeto usuario con: nombre, apellido, edad
Un objeto contacto con: email, teléfono
Un array hobbies con al menos 3 elementos
jsx
// index.jsx
<Perfil
usuario={{ nombre: "Ana", apellido: "García", edad: 28 }}
contacto={{ email: "ana@email.com", telefono: "123-456-789" }}
hobbies={["lectura", "natación", "cocina"]}
/>
Conclusión
Las props en React son fundamentales para la comunicación entre componentes. Pasar objetos como props permite organizar mejor los datos relacionados y hacer el código más mantenible. Recuerda que los objetos pueden anidarse y accederse mediante la notación de punto (objeto.propiedad.subpropiedad).
La depuración con console.log() es una herramienta invaluable para entender qué datos están llegando a tus componentes y cómo están estructurados
Comentarios
Publicar un comentario