6.5-4-Qué son las Props
Qué son las Props
Son datos que se pasan de un componente padre a un componente hijo. Las props son inmutables (el hijo no puede modificarlas directamente) y pueden ser de cualquier tipo:
Strings, números, booleanos
Arrays, objetos
Funciones (para comunicación hijo → padre)
Elementos React, componentes, etc.
Permiten la comunicación entre componentes(Padre al hijo).
Pueden ser de cualquier tipo: strings, números, arrays, objetos, funciones, etc.
Ejemplo Básico
// En el componente padre (App.js)
function App() {
const userName = "Agustín Navarro";
const age = 26;
return (
<Saludar
nombre={userName}
edad={age}
/>
);
}
// En el componente hijo (Saludar.js)
function Saludar(props) {
return (
<div>
<h1>Hola {props.nombre}</h1>
<p>Edad: {props.edad} años</p>
</div>
);}🔹 Problema: Si tenemos muchos props, el código se vuelve difícil de mantener.
2. Pasando Objetos como Props (Solución Óptima)
Ejemplo Mejorado
// En App.js
function App() {
const user = {
nombre: "Agustín Navarro",
edad: 26,
colorFavorito: "azul"
};
return <Saludar userInfo={user} />;
}
// En Saludar.js
function Saludar(props) {
return (
<div>
<h2>Hola {props.userInfo.nombre}</h2>
<p>Edad: {props.userInfo.edad} años</p>
<p>Color favorito: {props.userInfo.colorFavorito}</p>
</div>
);
}1. Pasando Funciones Básicas
Ejemplo Simple: Botón con Alerta
// Componente Padre (App.js)
function App() {
const saludar = () => {
alert("¡Hola desde el componente padre!");
};
return <BotonSaludar onClick={saludar} />;
}
// Componente Hijo (BotonSaludar.js)
function BotonSaludar(props) {
return (
<button onClick={props.onClick}>
Saludar
</button>
);
}🔹 Key Points:
La función se define en el padre y se pasa como prop (onClick)
El hijo ejecuta la función cuando ocurre un evento (click)
// Componente Padre (App.js)
function App() {
const saludar = () => {
alert("¡Hola desde el componente padre!");
};
return <BotonSaludar onClick={saludar} />;
}
// Componente Hijo (BotonSaludar.js)
function BotonSaludar(props) {
return (
<button onClick={props.onClick}>
Saludar
</button>
);
}La función se define en el padre y se pasa como prop (onClick)
El hijo ejecuta la función cuando ocurre un evento (click)
Ejemplo Avanzado: Pasar Funciones
// App.js
function App() {
const saludar = (nombre) => alert(`Hola ${nombre}!`);
return (
<Saludar
nombre="Agustín"
accion={saludar}
/>
);
}
// Saludar.js
function Saludar({ nombre, accion }) {
return (
<button onClick={() => accion(nombre)}>
Saludar a {nombre}
</button>
);
}
// App.js
function App() {
const saludar = (nombre) => alert(`Hola ${nombre}!`);
return (
<Saludar
nombre="Agustín"
accion={saludar}
/>
);
}
// Saludar.js
function Saludar({ nombre, accion }) {
return (
<button onClick={() => accion(nombre)}>
Saludar a {nombre}
</button>
);
}2. Pasando Parámetros a Funciones
Ejemplo Avanzado: Personalizando el Saludo
// App.js
function App() {
const usuario = {
nombre: "Agustín Navarro",
edad: 26
};
const saludarUsuario = (nombre) => {
console.log(`Hola ${nombre}`);
};
return <Saludador user={usuario} onSaludar={saludarUsuario} />;
}
// Saludador.js
function Saludador({ user, onSaludar }) {
return (
<div>
<button onClick={() => onSaludar(user.nombre)}>
Saludar a {user.nombre}
</button>
</div>
);
}
// App.js
function App() {
const usuario = {
nombre: "Agustín Navarro",
edad: 26
};
const saludarUsuario = (nombre) => {
console.log(`Hola ${nombre}`);
};
return <Saludador user={usuario} onSaludar={saludarUsuario} />;
}
// Saludador.js
function Saludador({ user, onSaludar }) {
return (
<div>
<button onClick={() => onSaludar(user.nombre)}>
Saludar a {user.nombre}
</button>
</div>
);
}Ejemplo sencillo:
// Definimos un objeto con las props
const usuario = {
nombre: "Ana",
edad: 25,
pais: "España"
};
// Pasamos todas las props de una vez usando ...
function TarjetaUsuario(props) {
return (
<div>
<h2>Nombre: {props.nombre}</h2>
<p>Edad: {props.edad}</p>
<p>País: {props.pais}</p>
</div>
);
}
// Uso del componente
function App() {
return <TarjetaUsuario {...usuario} />;
}
// Definimos un objeto con las props
const usuario = {
nombre: "Ana",
edad: 25,
pais: "España"
};
// Pasamos todas las props de una vez usando ...
function TarjetaUsuario(props) {
return (
<div>
<h2>Nombre: {props.nombre}</h2>
<p>Edad: {props.edad}</p>
<p>País: {props.pais}</p>
</div>
);
}
// Uso del componente
function App() {
return <TarjetaUsuario {...usuario} />;
}Componente Principal (App.js)
import React from 'react';
import Cat from './Cat'; // Importamos el componente Cat
function App() {
// Objeto gato que vamos a pasar
const gato = {
name: "Dexter",
year: 5 };
return (
<div>
<h1>App Principal</h1>
{/* Pasamos el objeto gato como prop al componente Cat */}
<Cat datosGato={gato} />
</div> );}// Versión más simple (sin destructuring)
function Cat(props) {
return (
<div>
<h2>Información del Gato</h2>
<p>Nombre: {props.datosGato.name}</p>
<p>Edad: {props.datosGato.year} años</p>
</div> );}
import React from 'react';
import Cat from './Cat'; // Importamos el componente Cat
function App() {
// Objeto gato que vamos a pasar
const gato = {
name: "Dexter",
year: 5 };
return (
<div>
<h1>App Principal</h1>
{/* Pasamos el objeto gato como prop al componente Cat */}
<Cat datosGato={gato} />
</div> );}// Versión más simple (sin destructuring)
function Cat(props) {
return (
<div>
<h2>Información del Gato</h2>
<p>Nombre: {props.datosGato.name}</p>
<p>Edad: {props.datosGato.year} años</p>
</div> );}
Imagina que tienes un componente Cat que guarda información de un gato en su estado:
import { useState } from "react";
const Cat = () => {
const [cat, setCat] = useState({ name: "Dexter", year: 5 });
const handleClick = () => {
// ¿Cómo actualizar solo el año sin perder el nombre?
setCat({ ...cat, year: cat.year + 1 });
};
return (
<>
<h2>
{cat.name} - {cat.year}
</h2>
<button onClick={handleClick} className="btn btn-dark mb-2">
Update year
</button>
</>
);
};
export default Cat;
Cat que guarda información de un gato en su estado:import { useState } from "react";
const Cat = () => {
const [cat, setCat] = useState({ name: "Dexter", year: 5 });
const handleClick = () => {
// ¿Cómo actualizar solo el año sin perder el nombre?
setCat({ ...cat, year: cat.year + 1 });
};
return (
<>
<h2>
{cat.name} - {cat.year}
</h2>
<button onClick={handleClick} className="btn btn-dark mb-2">
Update year
</button>
</>
);
};
export default Cat;App.js (pasando las props con ...gato
pasando las props con ...gato-import React from 'react';
import Cat from './Cat';
function App() {
const gato = {
name: "Dexter",
year: 5
};
return (
<div>
<h1>App Principal</h1>
{/* Pasamos todas las propiedades del objeto gato como props independientes */}
<Cat {...gato} />
</div>
);}export default App;
pasando las props con ...gato-import React from 'react';
import Cat from './Cat';
function App() {
const gato = {
name: "Dexter",
year: 5
};
return (
<div>
<h1>App Principal</h1>
{/* Pasamos todas las propiedades del objeto gato como props independientes */}
<Cat {...gato} />
</div>
);}export default App;function Cat({ name, year }) {
return (
<div>
<h2>Datos del Gato</h2>
<p>Nombre: {name}</p>
<p>Edad: {year} años</p>
</div>
);}export default Cat;
function Cat({ name, year }) { return ( <div> <h2>Datos del Gato</h2> <p>Nombre: {name}</p> <p>Edad: {year} años</p> </div> );}export default Cat;
📌 Ejemplo Básico
// Componente Padre
function App() {
const nombre = "Ana";
return <Saludo usuario={nombre} />;
}
// Componente Hijo
function Saludo(props) {
return <h1>¡Hola, {props.usuario}! 👋</h1>;
}Desestructurando Props (Mejor Legibilidad)
function Saludo({ usuario }) {
return <h1>¡Hola, {usuario}! 👋</h1>;
}🔥 Props con Children
Las props pueden incluir contenido entre las etiquetas del componente usando children:
function Tarjeta({ children }) {
return <div className="tarjeta">{children}</div>;
}
// Uso:
<Tarjeta>
<h2>Título</h2>
<p>Contenido aquí...</p>
</Tarjeta>Comunicación Hijo a Padre
El padre pasa una función al hijo, y el hijo la ejecuta cuando ocurre algo.
🏠 Componente Padre
function Padre() {
// Función que queremos que ejecute el hijo
const recibirSaludo = () => {
alert("¡El hijo me saludó! 👋");
};
return ( <div>
<h2>Yo soy el padre</h2>
{/* Pasamos la función como prop al hijo */}
<Hijo onSaludar={recibirSaludo} />
</div>);}function Hijo({ onSaludar }) {
return (<div>
<h3>Yo soy el hijo</h3>
{/* Cuando hagan click, ejecutamos la función del padre */}
<button onClick={onSaludar}>
Saludar al padre
</button>
</div> );
}¿Qué pasa?
El padre pasa
recibirSaludocomoonSaludaral hijoEl hijo recibe la función en sus props
Cuando el botón se clickea, el hijo ejecuta
onSaludar()¡El padre recibe el "saludo" y muestra la alerta!
💡 Analogía:
Es como cuando un niño (hijo) tiene un botón de emergencia que llama a sus padres (padre) cuando lo presiona. ¡El botón lo dieron los padres mismos!
📌 Sintaxis Básica
Componente Padre:
<Hijo nombre="Ana" edad={25} onSaludar={() => console.log("Hola!")} />Componente Hijo: (2 formas de acceder)
// Opción 1: Con parámetro "props"
function Hijo(props) {
return <p>{props.nombre} tiene {props.edad} años</p>;
}
// Opción 2: Destructurando
function Hijo({ nombre, edad, onSaludar }) {
return (
<>
<p>{nombre} tiene {edad} años</p>
<button onClick={onSaludar}>Saludar</button>
</>
);
}📌 Key Features de las Props
Flujo Unidireccional: Solo van de padre a hijo (no al revés).
Read-Only: El hijo no puede modificar sus props directamente. Si necesita cambios, el padre debe pasar una función (ej:
onSaludar).Default Props: Valores por defecto si no se pasan:
Hijo.defaultProps = { edad: 18 }; // Si no recibe "edad", usa 18PropTypes: Validar tipos (opcional, con librería
prop-types):Hijo.propTypes = { nombre: PropTypes.string.isRequired };
📌 Comunicación entre Componentes
Padre → Hijo: Directamente con props.
Hijo → Padre: Pasando una función como prop (ej:
onSaludar).Hermanos: El estado debe subirse al ancestro común (lifting state up).
📌 Ejemplo Avanzado
// Padre
function App() {
const [contador, setContador] = useState(0);
return (
<div>
<Hijo
valor={contador}
incrementar={() => setContador(contador + 1)}
/>
</div>
);
}
// Hijo
function Hijo({ valor, incrementar }) {
return (
<button onClick={incrementar}>
Clickeado {valor} veces
</button>
);
}❓ Preguntas Comunes
¿Props vs State?
Props: Datos externos (inmutables).
State: Datos internos del componente (mutables con
useState).
¿Pasar componentes como props? ¡Sí! (ej:
<Layout header={<Header />}>).
Ejemplos Detallados
1. Pasando funciones entre componentes
// Padre
function Padre() {
const handleAlert = () => alert("Mensaje desde el hijo");
return <Hijo ejecutarAlerta={handleAlert} />;
}
// Hijo
function Hijo({ ejecutarAlerta }) {
return <button onClick={ejecutarAlerta}>Mostrar Alerta</button>;
}2. Pasando objetos entre componentes
// Padre
function App() {
const usuario = { nombre: "Luisa", rol: "Admin" };
return <Perfil user={usuario} />;
}
// Hijo
function Perfil({ user }) {
return <p>{user.nombre} - {user.rol}</p>;
}3. Props por defecto jsx-Props por defecto
function Mensaje({ texto }) {
return <h1>{texto}</h1>;
}
Mensaje.defaultProps = { texto: "Hola Mundo" }; // Si no se pasa `texto`, usa este valor.
// Uso:
<Mensaje /> → Muestra "Hola Mundo".4. Children como Prop
function Tarjeta({ children }) {
return <div className="tarjeta">{children}</div>;
}
// Uso:
<Tarjeta>
<h2>Título</h2>
<p>Descripción</p>
</Tarjeta>Errores Comunes y Soluciones
Error: Modificar props directamente.
Solución: Usar estado en el padre y pasarlo como prop.Error: Olvidar pasar una prop requerida.
Solución: UsarPropTypesodefaultProps.Error: Pasar props innecesarias a componentes intermedios ("prop drilling").
Solución: Usar Context API o estado global (Redux, Zustand).
// Definimos un objeto con las props
const usuario = {
nombre: "Ana",
edad: 25,
pais: "España"
};
// Pasamos todas las props de una vez usando ...
function TarjetaUsuario(props) {
return (
<div>
<h2>Nombre: {props.nombre}</h2>
<p>Edad: {props.edad}</p>
<p>País: {props.pais}</p>
</div>
);
}
// Uso del componente
function App() {
return <TarjetaUsuario {...usuario} />;
}1. Renderizar Listas con map()
El método map() es esencial para transformar arrays en elementos de React.
import React from 'react';
const ListaDeUsuarios = () => {
const usuarios = ['Ana', 'Carlos', 'Luisa', 'Pedro'];
return (
<ul>
{usuarios.map((usuario, index) => (
<li key={index}>{usuario}</li>
))}
</ul>
);
};
export default ListaDeUsuarios;
🔹 Importante: Siempre usa una key única (preferiblemente un id en lugar del índice).
map() es esencial para transformar arrays en elementos de React.import React from 'react'; const ListaDeUsuarios = () => { const usuarios = ['Ana', 'Carlos', 'Luisa', 'Pedro']; return ( <ul> {usuarios.map((usuario, index) => ( <li key={index}>{usuario}</li> ))} </ul> ); }; export default ListaDeUsuarios;
key única (preferiblemente un id en lugar del índice).2. Actualizar Arrays en el Estado
Cuando trabajamos con el estado (useState), debemos evitar mutar arrays directamente. En su lugar, usamos métodos que retornan un nuevo array.
useState), debemos evitar mutar arrays directamente. En su lugar, usamos métodos que retornan un nuevo array.Añadir un elemento
const [tareas, setTareas] = useState(['Tarea 1', 'Tarea 2']);
const agregarTarea = () => {
setTareas([...tareas, 'Nueva Tarea']);
};
const [tareas, setTareas] = useState(['Tarea 1', 'Tarea 2']); const agregarTarea = () => { setTareas([...tareas, 'Nueva Tarea']); };
Eliminar un elemento
const eliminarTarea = (index) => {
setTareas(tareas.filter((_, i) => i !== index));
};
const eliminarTarea = (index) => { setTareas(tareas.filter((_, i) => i !== index)); };
Actualizar un elemento
const actualizarTarea = (index, nuevoTexto) => {
setTareas(tareas.map((tarea, i) =>
i === index ? nuevoTexto : tarea
));
};
const actualizarTarea = (index, nuevoTexto) => { setTareas(tareas.map((tarea, i) => i === index ? nuevoTexto : tarea )); };
3. Ordenar y Filtrar Arrays
Podemos aplicar métodos como sort() y filter() antes de renderizar.
const numeros = [3, 1, 4, 2];
const numerosOrdenados = [...numeros].sort((a, b) => a - b);
const mayoresQueDos = numeros.filter(num => num > 2);
sort() y filter() antes de renderizar.const numeros = [3, 1, 4, 2]; const numerosOrdenados = [...numeros].sort((a, b) => a - b); const mayoresQueDos = numeros.filter(num => num > 2);
4. Arrays de Objetos
Es común trabajar con arrays de objetos, como datos de una API.
const [productos, setProductos] = useState([
{ id: 1, nombre: 'Laptop', precio: 1000 },
{ id: 2, nombre: 'Teléfono', precio: 500 },
]);
return (
<ul>
{productos.map((producto) => (
<li key={producto.id}>
{producto.nombre} - ${producto.precio}
</li>
))}
</ul>
);
const [productos, setProductos] = useState([ { id: 1, nombre: 'Laptop', precio: 1000 }, { id: 2, nombre: 'Teléfono', precio: 500 }, ]); return ( <ul> {productos.map((producto) => ( <li key={producto.id}> {producto.nombre} - ${producto.precio} </li> ))} </ul> );
Pasar Objeto de App a Componente Cat
Aquí tienes el ejemplo más simple posible de cómo pasar un objeto gato desde el componente principal App al componente Cat:
🏠 Componente Principal (App.js)
import React from 'react';
import Cat from './Cat'; // Importamos el componente Cat
function App() {
// Objeto gato que vamos a pasar
const gato = {
name: "Dexter",
year: 5 };
return ( <div>
<h1>App Principal</h1>
{/* Pasamos el objeto gato como prop al componente Cat */}
<Cat datosGato={gato} />
</div> );}// Versión más simple (sin destructuring)function Cat(props) {
return (<div>
<h2>Información del Gato</h2>
<p>Nombre: {props.datosGato.name}</p>
<p>Edad: {props.datosGato.year} años</p>
</div>
);Lo que verías en pantalla:
App Principal Información del Gato Nombre: Dexter Edad: 5 años💡 Explicación breve:
En
App.jscreamos el objetogatoLo pasamos al componente
Catcon el nombredatosGatoEn
Cat.jsaccedemos a las propiedades conprops.datosGato.nameyprops.datosGato.year¿Más simple imposible, verdad? 😺 Puedes agregar más propiedades al objeto gato si quieres (como color, raza, etc.) y se pasarán automáticamente al componente hijo
Comentarios
Publicar un comentario