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

jsx-cadena-entero
// 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

jsx-Pasando Objetos como Props
// 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

jsx-Funciones Básicas
// 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)

Ejemplo Avanzado: Pasar Funciones

jsx- 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>
  );
}

2. Pasando Parámetros a Funciones

Ejemplo Avanzado: Personalizando el Saludo

jsx-Pasando Parámetros a Funciones
// 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:

jsx-operator-objeto 
// 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)

jsx-Pasar Objeto de App a Componente Cat
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:

jsx- spread -Actualizar un objeto
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;

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

jsx-props-cadena
// 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)

jsx-Desestructurando Props
function Saludo({ usuario }) {
  return <h1>¡Hola, {usuario}! 👋</h1>;
}

🔥 Props con Children

Las props pueden incluir contenido entre las etiquetas del componente usando children:

jsx-Props con 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

jsx-Comunicación Hijo a 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>);}
jsx-Componente Hijo
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?

  1. El padre pasa recibirSaludo como onSaludar al hijo

  2. El hijo recibe la función en sus props

  3. Cuando el botón se clickea, el hijo ejecuta onSaludar()

  4. ¡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:

jsx
Copy
Download
<Hijo nombre="Ana" edad={25} onSaludar={() => console.log("Hola!")} />

Componente Hijo: (2 formas de acceder)

jsx
Copy
Download
// 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

  1. Flujo Unidireccional: Solo van de padre a hijo (no al revés).

  2. Read-Only: El hijo no puede modificar sus props directamente. Si necesita cambios, el padre debe pasar una función (ej: onSaludar).

  3. Default Props: Valores por defecto si no se pasan:

    jsx
    Copy
    Download
    Hijo.defaultProps = { edad: 18 }; // Si no recibe "edad", usa 18
  4. PropTypes: Validar tipos (opcional, con librería prop-types):

    jsx
    Copy
    Download
    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

jsx-contador
Copy
Download
// 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

jsx-Pasando funciones entre componentes
Download
// 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

jsx-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

jsx-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: Usar PropTypes o defaultProps.

  • Error: Pasar props innecesarias a componentes intermedios ("prop drilling").
    Solución: Usar Context API o estado global (Redux, Zustand).


jsx-operator-objeto 
// 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.

jsx- Renderizar Listas con map()
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).

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.

Añadir un elemento

jsx-Añadir un elemento
const [tareas, setTareas] = useState(['Tarea 1', 'Tarea 2']);

const agregarTarea = () => {
  setTareas([...tareas, 'Nueva Tarea']);
};

Eliminar un elemento

jsx-Eliminar un elemento
const eliminarTarea = (index) => {
  setTareas(tareas.filter((_, i) => i !== index));
};

Actualizar un elemento

jsx-Actualizar un elemento
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.

jsx
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.

jsx-Arrays de Objetos
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)

jsx-Objeto gato que vamos a pasar
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:

text
App Principal

Información del Gato
Nombre: Dexter
Edad: 5 años

💡 Explicación breve:

  1. En App.js creamos el objeto gato

  2. Lo pasamos al componente Cat con el nombre datosGato

  3. En Cat.js accedemos a las propiedades con props.datosGato.name y props.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

Entradas más populares de este blog

6.8-23-pasando funciones a nuestro componente

6.12-0-3- Spread Operator