MÓDULO 1: UI MODERNA

Renderizado Condicional

A veces quieres mostrar algo solo si se cumple una condición. "Si el usuario está logueado, muestra el panel. Si no, muestra el login." El renderizado condicional permite que tu UI sea dinámica y responda a diferentes estados.


1. if/else en Componentes

Puedes usar if/else antes del return para decidir qué renderizar.

import { useState } from 'react';

export default function App() {
    const [estaLogueado, setEstaLogueado] = useState(false);

    // Decidir qué renderizar ANTES del return
    let contenido;

    if (estaLogueado) {
        contenido = <h1>Bienvenido al panel</h1>;
    } else {
        contenido = <h1>Por favor, inicia sesión</h1>;
    }

    return (
        <div>
            {contenido}
            <button onClick={() => setEstaLogueado(!estaLogueado)}>
                {estaLogueado ? "Cerrar sesión" : "Iniciar sesión"}
            </button>
        </div>
    );
}

2. Operador Ternario (? :)

La forma más común de renderizado condicional. Es como un if/else en una línea.

import { useState } from 'react';

export default function App() {
    const [estaLogueado, setEstaLogueado] = useState(false);

    return (
        <div>
            <!-- Sintaxis: condición ? si es verdadero : si es falso -->
            {estaLogueado ? (
                <h1>Bienvenido</h1>
            ) : (
                <h1>Inicia sesión</h1>
            )}

            <button onClick={() => setEstaLogueado(!estaLogueado)}>
                {estaLogueado ? "Cerrar sesión" : "Iniciar sesión"}
            </button>
        </div>
    );
}

3. Operador AND (&&)

Muestra algo solo si la condición es verdadera. Si es falsa, no muestra nada.

import { useState } from 'react';

export default function App() {
    const [tieneNotificaciones, setTieneNotificaciones] = useState(true);

    return (
        <div>
            <!-- Sintaxis: condición && qué mostrar -->
            {tieneNotificaciones && (
                <div className="notificacion">
                    ¡Tienes nuevos mensajes!
                </div>
            )}

            <button onClick={() => setTieneNotificaciones(!tieneNotificaciones)}>
                Marcar como leído
            </button>
        </div>
    );
}

¿Cuándo usar cada uno?

  • Ternario (?:): Cuando tienes dos opciones (mostrar A o mostrar B).
  • AND (&&): Cuando quieres mostrar algo o nada.

4. Renderizado Condicional con Componentes

Puedes renderizar componentes diferentes según una condición.

// Componentes diferentes
function PanelAdmin() {
    return <div>Panel de administración</div>;
}

function PanelUsuario() {
    return <div>Panel de usuario</div>;
}

function LoginForm() {
    return <div>Formulario de login</div>;
}

// Componente principal
import { useState } from 'react';

export default function App() {
    const [usuario, setUsuario] = useState(null);
    const [esAdmin, setEsAdmin] = useState(false);

    return (
        <div>
            {!usuario ? (
                <LoginForm />
            ) : esAdmin ? (
                <PanelAdmin />
            ) : (
                <PanelUsuario />
            )}
        </div>
    );
}

5. Renderizado Basado en Listas

Mostrar contenido diferente según si una lista está vacía o tiene elementos.

import { useState } from 'react';

export default function ListaTareas() {
    const [tareas, setTareas] = useState([]);

    return (
        <div>
            {tareas.length === 0 ? (
                <p>No tienes tareas. ¡Relájate!</p>
            ) : (
                <ul>
                    {tareas.map((tarea) => (
                        <li key={tarea.id}>{tarea.texto}</li>
                    ))}
                </ul>
            )}
        </div>
    );
}

6. Renderizado Condicional con Estado Complejo

Mostrar diferentes UI según múltiples condiciones.

import { useState } from 'react';

export default function Descarga() {
    const [estado, setEstado] = useState("inicio");
    // Estados posibles: "inicio", "descargando", "completado", "error"

    return (
        <div>
            {estado === "inicio" && (
                <button onClick={() => setEstado("descargando")}>
                    Descargar
                </button>
            )}

            {estado === "descargando" && (
                <p>⏳ Descargando...</p>
            )}

            {estado === "completado" && (
                <p>✓ ¡Descarga completada!</p>
            )}

            {estado === "error" && (
                <p>❌ Error en la descarga</p>
            )}
        </div>
    );
}

7. Caso Práctico: Sistema de Autenticación

Crea un sistema de login con renderizado condicional.

import { useState } from 'react';

export default function App() {
    const [usuario, setUsuario] = useState(null);
    const [email, setEmail] = useState("");
    const [contraseña, setContraseña] = useState("");

    const handleLogin = () => {
        if (email && contraseña) {
            setUsuario({ email, nombre: email.split("@")[0] });
            setEmail("");
            setContraseña("");
        }
    };

    const handleLogout = () => {
        setUsuario(null);
    };

    return (
        <div>
            {usuario ? (
                <div>
                    <h1>Bienvenido, {usuario.nombre}!</h1>
                    <p>Email: {usuario.email}</p>
                    <button onClick={handleLogout}>
                        Cerrar sesión
                    </button>
                </div>
            ) : (
                <div>
                    <h1>Iniciar Sesión</h1>
                    <input
                        type="email"
                        value={email}
                        onChange={(e) => setEmail(e.target.value)}
                        placeholder="Email"
                    />
                    <input
                        type="password"
                        value={contraseña}
                        onChange={(e) => setContraseña(e.target.value)}
                        placeholder="Contraseña"
                    />
                    <button onClick={handleLogin}>
                        Iniciar sesión
                    </button>
                </div>
            )}
        </div>
    );
}

8. Caso Práctico: Carrito con Renderizado Condicional

Muestra diferentes mensajes según el estado del carrito.

import { useState } from 'react';

export default function Carrito() {
    const [carrito, setCarrito] = useState([]);

    const agregarProducto = (producto) => {
        setCarrito([...carrito, producto]);
    };

    const vaciarCarrito = () => {
        setCarrito([]);
    };

    return (
        <div>
            <h1>Mi Carrito</h1>

            {carrito.length === 0 ? (
                <div>
                    <p>Tu carrito está vacío</p>
                    <button onClick={() => agregarProducto("Laptop")}>
                        Agregar producto
                    </button>
                </div>
            ) : (
                <div>
                    <p>Tienes {carrito.length} producto(s)</p>
                    <ul>
                        {carrito.map((item, index) => (
                            <li key={index}>{item}</li>
                        ))}
                    </ul>
                    <button onClick={vaciarCarrito}>
                        Vaciar carrito
                    </button>
                    <button>Comprar</button>
                </div>
            )}
        </div>
    );
}

🛠️ Tu Misión

Usa CodeSandbox (React).

  1. Crea un componente que muestre "Logueado" o "No logueado" según un estado booleano.
  2. Usa el operador ternario para mostrar un botón diferente según el estado.
  3. Usa el operador AND para mostrar una notificación solo si hay mensajes nuevos.
  4. Crea un componente que renderice diferentes componentes según el tipo de usuario (admin/usuario).
  5. Crea una lista que muestre "Lista vacía" cuando no hay elementos, y la lista cuando hay.
  6. Crea un sistema de login simple con renderizado condicional.
  7. Bonus: Crea un componente que muestre diferentes estados (cargando, completado, error) con renderizado condicional.