20-props
Props en React - Explicación Sencilla con Ejemplos
Las props (abreviatura de "properties") son datos que se pasan de un componente padre a un componente hijo en React. Son inmutables (no se pueden modificar dentro del componente hijo) y permiten que los componentes sean reutilizables y dinámicos.
Concepto Básico
Imagina que un componente es una función en JavaScript. Las props serían como los parámetros que le pasas a esa función.
Ejemplo 1: Componente de Saludo Simple
jsx
// Componente HIJO (que recibe props)
function Saludo(props) {
return <h1>¡Hola, {props.nombre}!</h1>;
}
// Componente PADRE (que pasa props)
function App() {
return (
<div>
<Saludo nombre="Ana" />
<Saludo nombre="Carlos" />
<Saludo nombre="María" />
</div>
);
}
Resultado:
¡Hola, Ana!
¡Hola, Carlos!
¡Hola, María!
Ejemplo 2: Tarjeta de Usuario
jsx
// Componente HIJO
function TarjetaUsuario(props) {
return (
<div className="tarjeta">
<img src={props.foto} alt={props.nombre} />
<h2>{props.nombre}</h2>
<p>Edad: {props.edad}</p>
<p>{props.biografia}</p>
</div>
);
}
// Componente PADRE
function App() {
return (
<div>
<TarjetaUsuario
foto="https://ejemplo.com/ana.jpg"
nombre="Ana García"
edad={28}
biografia="Desarrolladora web apasionada por React"
/>
<TarjetaUsuario
foto="https://ejemplo.com/carlos.jpg"
nombre="Carlos López"
edad={32}
biografia="Diseñador UX/UI"
/>
</div>
);
}
Ejemplo 3: Lista de Tareas (más realista)
jsx
// Componente para una sola tarea
function Tarea(props) {
return (
<li className={props.completada ? "completada" : ""}>
<span>{props.texto}</span>
<button onClick={() => props.onCompletar(props.id)}>
{props.completada ? "Desmarcar" : "Completar"}
</button>
</li>
);
}
// Componente para la lista completa
function ListaTareas() {
const [tareas, setTareas] = React.useState([
{ id: 1, texto: "Aprender React", completada: true },
{ id: 2, texto: "Practicar Props", completada: false },
{ id: 3, texto: "Crear mi primer proyecto", completada: false }
]);
const completarTarea = (id) => {
setTareas(tareas.map(tarea =>
tarea.id === id ? {...tarea, completada: !tarea.completada} : tarea
));
};
return (
<ul>
{tareas.map((tarea) => (
<Tarea
key={tarea.id}
id={tarea.id}
texto={tarea.texto}
completada={tarea.completada}
onCompletar={completarTarea}
/>
))}
</ul>
);
}
Ejemplo 4: Props con Destructuring (forma más común)
jsx
// En lugar de usar props.nombre, props.edad...
// Podemos desestructurar directamente
function Perfil({ nombre, edad, profesion, ciudad = "Desconocida" }) {
// Ciudad tiene un valor por defecto si no se proporciona
return (
<div>
<h3>{nombre}</h3>
<p><strong>Edad:</strong> {edad}</p>
<p><strong>Profesión:</strong> {profesion}</p>
<p><strong>Ciudad:</strong> {ciudad}</p>
</div>
);
}
function App() {
return (
<Perfil
nombre="Laura"
edad={25}
profesion="Ingeniera"
// No pasamos ciudad, usará el valor por defecto
/>
);
}
Ejemplo 5: Props.children - Contenido especial
jsx
// Componente Caja que envuelve contenido
function Caja({ color, children }) {
return (
<div style={{
backgroundColor: color,
padding: '20px',
margin: '10px',
borderRadius: '5px'
}}>
{children} {/* Esto muestra lo que pongas DENTRO del componente */}
</div>
);
}
function App() {
return (
<div>
<Caja color="lightblue">
<h2>Título dentro de la caja</h2>
<p>Este párrafo también está dentro de la caja azul.</p>
</Caja>
<Caja color="lightgreen">
<p>Solo un texto simple en verde.</p>
</Caja>
</div>
);
}
Resumen de Conceptos Clave
Flujo unidireccional: Las props solo van de padre a hijo
Inmutables: No se pueden modificar dentro del componente hijo
Tipos de props: Pueden ser strings, números, arrays, objetos, funciones, elementos JSX, etc.
Propiedades especiales:
key: Para listas (no es una prop accesible)
children: Contenido entre las etiquetas del componente
Valores por defecto: Se pueden definir valores predeterminados
PropTypes: Para validar tipos de datos (opcional pero recomendado)
Consejos Prácticos
Usa destructuring para mayor claridad
Nombra las props de forma descriptiva
Considera usar TypeScript o PropTypes para validación
Si necesitas modificar datos, usa state en lugar de props
Tutorial: 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/
│ ├── Coffe.jsx
│ └── Usuarios.jsx
├── index.jsx
└── ...
🚀 Paso 1: Componente Básico con Props
Archivo: src/components/Usuarios.jsx
jsx
// Versión 1: Usando props como objeto
export function Usuarios(props) {
return <h1>{props.nombre}</h1>;
}
Archivo: src/index.jsx
jsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { Usuarios } from './components/Usuarios';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<Usuarios nombre="frank" />
<Usuarios nombre="pedro" />
<Usuarios nombre="frank2" />
<Usuarios nombre="frank3" />
</React.StrictMode>
);
Resultado:
text
frank
pedro
frank2
frank3
🔧 Paso 2: Desestructuración de Props
¿Qué es la desestructuración?
Es una característica de JavaScript que permite extraer valores de objetos de forma más concisa.
Archivo actualizado: src/components/Usuarios.jsx
jsx
// Versión 2: Desestructurando props
export function Usuarios({ nombre }) {
return <h1>{nombre}</h1>;
}
Ventajas:
Código más limpio y legible
No es necesario escribir props. repetidamente
Especificas explícitamente qué props esperas recibir
📊 Paso 3: Múltiples Props Simples
Archivo: src/index.jsx
jsx
// Pasando múltiples props
root.render(
<React.StrictMode>
<Usuarios nombre="frank" edad={21} />
<Usuarios nombre="pedro" edad={21} />
</React.StrictMode>
);
Archivo: src/components/Usuarios.jsx
jsx
// Recibiendo múltiples props
export function Usuarios({ nombre, edad }) {
return <h1>{nombre} {edad}</h1>;
}
Resultado:
text
frank 21
pedro 21
🏗️ Paso 4: Props con Objetos Anidados
Ejemplo Real: Dirección de Usuario
Archivo: src/index.jsx
jsx
root.render(
<React.StrictMode>
<Usuarios
nombre="frank"
edad={21}
direccion={{
calle: "calle san martin",
ciudad: "Lima",
pais: "Peru"
}}
/>
</React.StrictMode>
);
📝 Nota: Observa la sintaxis:
direccion={ ... } - Llaves para indicar código JavaScript
{ ... } - Objeto literal dentro de las llaves
Propiedades anidadas: calle, ciudad, pais
🔍 Paso 5: Accediendo a Objetos Anidados
Archivo: src/components/Usuarios.jsx
jsx
// Versión 1: Usando props.direccion
export function Usuarios(props) {
return (
<div>
<h1>{props.nombre}</h1>
<h1>{props.edad}</h1>
{/* Accediendo a propiedades anidadas */}
<h2>Calle: {props.direccion.calle}</h2>
<h2>Ciudad: {props.direccion.ciudad}</h2>
<h2>País: {props.direccion.pais}</h2>
</div>
);
}
Alternativa con desestructuración anidada:
jsx
// Versión 2: Desestructuración anidada
export function Usuarios({
nombre,
edad,
direccion: { calle, ciudad, pais }
}) {
return (
<div>
<h1>{nombre}</h1>
<h1>{edad}</h1>
<h2>Calle: {calle}</h2>
<h2>Ciudad: {ciudad}</h2>
<h2>País: {pais}</h2>
</div>
);
}
🎨 Paso 6: Mejorando la Presentación con Emojis
Archivo mejorado: src/components/Usuarios.jsx
jsx
export function Usuarios(props) {
return (
<div>
<h1>👤 {props.nombre}</h1>
<h1>🎂 {props.edad} años</h1>
<h2>📍 Calle: {props.direccion.calle}</h2>
<h2>🏙️ Ciudad: {props.direccion.ciudad}</h2>
<h2>🇵🇪 País: {props.direccion.pais}</h2>
</div>
);
}
📝 Nota: React soporta emojis directamente. Puedes copiarlos de:
Sitios web como Emojipedia
Tablas de caracteres Unicode
Atajos de teclado de tu sistema operativo
🔧 Paso 7: Depurando con console.log()
Archivo: src/components/Usuarios.jsx
jsx
export function Usuarios(props) {
// Depuración: ver qué props llegan
console.log("Props recibidos:", props);
console.log("Dirección completa:", props.direccion);
console.log("Ciudad:", props.direccion.ciudad);
return (
<div>
<h1>{props.nombre}</h1>
<h1>{props.edad}</h1>
<h2>Calle: {props.direccion.calle}</h2>
</div>
);
}
Resultado en consola:
javascript
{
nombre: "frank",
edad: 21,
direccion: {
calle: "calle san martin",
ciudad: "Lima",
pais: "Peru"
}
}
🧪 Ejercicios Prácticos
Ejercicio 1: Componente Producto con Especificaciones
jsx
// En index.jsx
<Producto
nombre="Laptop Gamer"
precio={1200}
especificaciones={{
procesador: "Intel i7",
ram: "16GB",
almacenamiento: "512GB SSD",
grafica: "RTX 3060"
}}
/>
// En Producto.jsx
export function Producto({ nombre, precio, especificaciones }) {
return (
<div>
<h2>🖥️ {nombre}</h2>
<p>💰 Precio: ${precio}</p>
<h3>Especificaciones:</h3>
<ul>
<li>💻 Procesador: {especificaciones.procesador}</li>
<li>🧠 RAM: {especificaciones.ram}</li>
<li>💾 Almacenamiento: {especificaciones.almacenamiento}</li>
<li>🎮 Gráfica: {especificaciones.grafica}</li>
</ul>
</div>
);
}
Ejercicio 2: Componente Estudiante con Calificaciones
jsx
// En index.jsx
<Estudiante
nombre="Ana López"
edad={20}
calificaciones={{
matematica: 18,
historia: 16,
programacion: 20,
ingles: 17
}}
/>
// Tu solución aquí...
📊 Comparación: Diferentes Formas de Trabajar con Props
⚠️ Errores Comunes y Soluciones
Error 1: Acceder a propiedad undefined
jsx
// ❌ Incorrecto - Error si direccion no existe
<h2>{props.direccion.ciudad}</h2>
// ✅ Correcto - Verificación opcional
<h2>{props.direccion?.ciudad || "No especificada"}</h2>
Error 2: Olvidar llaves para objetos
jsx
// ❌ Incorrecto
<Usuario direccion="{ calle: '...', ciudad: '...' }" />
// ✅ Correcto
<Usuario direccion={{ calle: '...', ciudad: '...' }} />
Error 3: No desestructurar correctamente
jsx
// ❌ Incorrecto
export function Usuario({ props.nombre }) { ... }
// ✅ Correcto
export function Usuario({ nombre }) { ... }
🎓 Preguntas de Reflexión
¿Cuándo es mejor usar objetos como props vs props individuales?
Usa objetos cuando las propiedades están relacionadas lógicamente (ej: dirección, especificaciones)
¿Qué ventaja tiene la desestructuración anidada?
Reduce el código y hace explícitas las propiedades que usas
¿Cómo manejarías un objeto prop opcional?
Con el operador ?. (optional chaining) o valores por defecto
🏆 Desafío Final: Sistema de Biblioteca
Crea un componente Libro que reciba:
jsx
<Libro
titulo="Cien años de soledad"
autor={{
nombre: "Gabriel García Márquez",
nacionalidad: "Colombiano",
fechaNacimiento: "1927-03-06"
}}
detalles={{
paginas: 417,
genero: "Realismo mágico",
isbn: "978-3-16-148410-0",
editorial: "Sudamericana"
}}
disponible={true}
/>
Requisitos:
Muestra toda la información con emojis apropiados
Usa desestructuración anidada
Agrega estilos condicionales (ej: color rojo si no está disponible)
Incluye un console.log para depuración
✅ Resumen de Conceptos Clave
Objetos como props: Permiten agrupar datos relacionados
Desestructuración: Simplifica el acceso a props
Propiedades anidadas: Accede con objeto.propiedad.subpropiedad
Depuración: Usa console.log(props) para ver qué datos llegan
Sintaxis: Objetos van entre dobles llaves {{ ... }}
📚 Recursos Adicionales
MDN Web Docs: Desestructuración en JavaScript
React Documentation: Passing Props to a Component
Emoji Unicode Tables: Para encontrar emojis apropiados
Prettier: Formateo automático de código (Ctrl+K, Ctrl+D en VS Code)
¡Recuerda! La práctica es esencial. Experimenta con diferentes estructuras de objetos y encuentra el estilo que mejor se adapte a tu proyecto. ¡Feliz codificación!
Comentarios
Publicar un comentario