MÓDULO 1: UI MODERNA

Propiedades (Props)

Los componentes sin propiedades son aburridos. Todos hacen lo mismo. Las Props (propiedades) permiten que un componente reciba datos y sea diferente cada vez que lo usas. Es como pasar argumentos a una función.


1. ¿Qué son las Props?

Las props son datos que pasas a un componente. El componente las recibe como parámetros.

// Componente que recibe props
function Saludo(props) {
    return <h1>Hola {props.nombre}</h1>;
}

// Usar el componente pasando props
export default function App() {
    return (
        <div>
            <Saludo nombre="Juan" />
            <Saludo nombre="Ana" />
            <Saludo nombre="Pedro" />
        </div>
    );
}

¿Cómo funciona?

  • Pasas datos como atributos: <Saludo nombre="Juan" />
  • El componente recibe un objeto props con esos datos.
  • Accedes a ellos con props.nombre, props.edad, etc.

2. Destructuring de Props

En lugar de escribir props.nombre cada vez, puedes extraer las propiedades directamente.

// Forma antigua (sin destructuring)
function Tarjeta(props) {
    return (
        <div>
            <h2>{props.titulo}</h2>
            <p>{props.descripcion}</p>
        </div>
    );
}

// Forma moderna (con destructuring) - RECOMENDADO
function Tarjeta({ titulo, descripcion }) {
    return (
        <div>
            <h2>{titulo}</h2>
            <p>{descripcion}</p>
        </div>
    );
}

3. Múltiples Props

Puedes pasar tantas propiedades como necesites.

// Componente que recibe múltiples props
function Perfil({ nombre, edad, ciudad, profesion }) {
    return (
        <div className="perfil">
            <h2>{nombre}</h2>
            <p>Edad: {edad}</p>
            <p>Ciudad: {ciudad}</p>
            <p>Profesión: {profesion}</p>
        </div>
    );
}

// Usar el componente
export default function App() {
    return (
        <div>
            <Perfil 
                nombre="Juan" 
                edad={25} 
                ciudad="Madrid" 
                profesion="Desarrollador" 
            />
        </div>
    );
}

4. Props con Diferentes Tipos de Datos

Las props pueden ser strings, números, booleanos, arrays, objetos, o incluso funciones.

// Componente que recibe diferentes tipos
function Producto({ nombre, precio, enStock, colores, detalles, onClick }) {
    return (
        <div>
            <h3>{nombre}</h3>
            <p>Precio: ${precio}</p>
            <p>En stock: {enStock ? "Sí" : "No"}</p>
            <p>Colores: {colores.join(", ")}</p>
            <p>Descripción: {detalles.descripcion}</p>
            <button onClick={onClick}>Comprar</button>
        </div>
    );
}

// Usar el componente
export default function App() {
    const handleCompra = () => {
        alert("¡Producto comprado!");
    };

    return (
        <Producto
            nombre="Laptop"
            precio={999.99}
            enStock={true}
            colores={["Negro", "Plata", "Oro"]}
            detalles={{ descripcion: "Laptop de alta gama", marca: "TechCorp" }}
            onClick={handleCompra}
        />
    );
}

5. Props por Defecto

Puedes asignar valores por defecto a las props.

// Forma 1: Parámetros por defecto en la función
function Boton({ texto = "Click", color = "azul" }) {
    return (
        <button className={`btn-${color}`}>
            {texto}
        </button>
    );
}

// Usar el componente
<Boton /> // Usa valores por defecto
<Boton texto="Enviar" /> // Personaliza el texto
<Boton texto="Eliminar" color="rojo" /> // Personaliza todo

6. Props Booleanas

Cuando una prop es true, puedes escribirla sin valor.

// Componente que recibe un booleano
function Tarjeta({ titulo, destacado }) {
    return (
        <div className={destacado ? "tarjeta destacada" : "tarjeta"}>
            <h3>{titulo}</h3>
        </div>
    );
}

// Usar el componente
<Tarjeta titulo="Normal" />
<Tarjeta titulo="Destacada" destacado={true} />
<Tarjeta titulo="Destacada" destacado /> // Forma corta

7. Caso Práctico: Lista de Productos

Crea componentes reutilizables para mostrar productos.

// Componente de producto individual
function ProductoItem({ nombre, precio, imagen }) {
    return (
        <div className="producto">
            <img src={imagen} alt={nombre} />
            <h3>{nombre}</h3>
            <p>Precio: ${precio}</p>
            <button>Agregar al carrito</button>
        </div>
    );
}

// Componente principal
export default function App() {
    const productos = [
        { id: 1, nombre: "Laptop", precio: 999, imagen: "laptop.jpg" },
        { id: 2, nombre: "Mouse", precio: 29, imagen: "mouse.jpg" },
        { id: 3, nombre: "Teclado", precio: 79, imagen: "teclado.jpg" }
    ];

    return (
        <div>
            <h1>Tienda Online</h1>
            <div className="productos">
                {productos.map((producto) => (
                    <ProductoItem
                        key={producto.id}
                        nombre={producto.nombre}
                        precio={producto.precio}
                        imagen={producto.imagen}
                    />
                ))}
            </div>
        </div>
    );
}

8. Caso Práctico: Tarjeta de Usuario

Crea una tarjeta reutilizable para mostrar información de usuarios.

// Componente de tarjeta de usuario
function TarjetaUsuario({ nombre, edad, ciudad, avatar, esAdmin }) {
    return (
        <div className="tarjeta-usuario">
            <img src={avatar} alt={nombre} className="avatar" />
            <h3>{nombre}</h3>
            <p>Edad: {edad}</p>
            <p>Ciudad: {ciudad}</p>
            {esAdmin && <span className="badge">Admin</span>}
        </div>
    );
}

// Usar el componente
export default function App() {
    return (
        <div>
            <TarjetaUsuario
                nombre="Juan"
                edad={25}
                ciudad="Madrid"
                avatar="juan.jpg"
                esAdmin={false}
            />
            <TarjetaUsuario
                nombre="Ana"
                edad={28}
                ciudad="Barcelona"
                avatar="ana.jpg"
                esAdmin={true}
            />
        </div>
    );
}

🛠️ Tu Misión

Usa CodeSandbox (React).

  1. Crea un componente Boton que reciba una prop texto y la muestre.
  2. Crea un componente Tarjeta que reciba titulo y descripcion.
  3. Crea un componente Perfil que reciba nombre, edad y ciudad, y muestre toda la información.
  4. Crea un componente Producto que reciba nombre, precio e imagen.
  5. Usa el componente Producto 3 veces con diferentes datos.
  6. Bonus: Crea un array de productos y usa .map() para mostrar cada uno.