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

  1. Flujo unidireccional: Las props solo van de padre a hijo

  2. Inmutables: No se pueden modificar dentro del componente hijo

  3. Tipos de props: Pueden ser strings, números, arrays, objetos, funciones, elementos JSX, etc.

  4. Propiedades especiales:

    • key: Para listas (no es una prop accesible)

    • children: Contenido entre las etiquetas del componente

  5. Valores por defecto: Se pueden definir valores predeterminados

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

  1. Aprender a pasar objetos como props

  2. Entender cómo acceder a propiedades anidadas dentro de objetos

  3. Practicar con diferentes formas de recibir props

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

Método

Ventajas

Desventajas

Cuándo Usar

props.propiedad

Simple, explícito

Código repetitivo

Pocas props

Desestructuración simple

Código más limpio

Fijo, menos flexible

Props conocidas

Desestructuración anidada

Muy conciso

Complejo para objetos profundos

Objetos planos

console.log(props)

Gran para depuración

Solo desarrollo

Depuración


⚠️ 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

  1. ¿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)

  2. ¿Qué ventaja tiene la desestructuración anidada?

    • Reduce el código y hace explícitas las propiedades que usas

  3. ¿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:

  1. Muestra toda la información con emojis apropiados

  2. Usa desestructuración anidada

  3. Agrega estilos condicionales (ej: color rojo si no está disponible)

  4. Incluye un console.log para depuración



✅ Resumen de Conceptos Clave

  1. Objetos como props: Permiten agrupar datos relacionados

  2. Desestructuración: Simplifica el acceso a props

  3. Propiedades anidadas: Accede con objeto.propiedad.subpropiedad

  4. Depuración: Usa console.log(props) para ver qué datos llegan

  5. Sintaxis: Objetos van entre dobles llaves {{ ... }}


📚 Recursos Adicionales

  1. MDN Web Docs: Desestructuración en JavaScript

  2. React Documentation: Passing Props to a Component

  3. Emoji Unicode Tables: Para encontrar emojis apropiados

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

Entradas más populares de este blog

11. Creando un proyecto react con create-react-app

29. useEffect

38. 4 Routers