El renderizado condicional consiste en mostrar o no un contenido en función de una condición lógica o boolean.
Por ejemplo, si queremos mostrar un mensaje de bienvenida solo si el usuario está autenticado
En React, esto se logra utilizando estructuras de control normales de JavaScript, como if, else, operadores ternarios o lógicos, dentro del código JSX.
Sin embargo, dentro de las llaves {} del JSX solo podemos usar expresiones (código que devuelve un valor), por lo que no podemos usar sentencias de bloque como if o switch directamente ahí dentro.
Entonces, ¿cómo lo hacemos? Tenemos distintas opciones dependiendo del caso (como siempre, vamos).
- AND (
&&): Para mostrar algo opcionalmente si se cumple una condición. - Ternario (
?): Para alternar entre dos estados visuales (Mostrar/Ocultar, Login/Logout). - Early Return (
if): Para bloquear el renderizado completo (Carga, Errores, Permisos).
El operador ternario ?
Dentro de las llaves {} de JSX no podemos meter un if/else (porque no devuelven nada)
La primera opción para renderizado condicional en React es el Operador Ternario.
Es perfecto para la lógica de “Una cosa u Otra”.
// Estructura: condición ? verdadero : falso
function PanelUsuario({ isLogged }) {
return (
<div>
{isLogged ? (
<button>Cerrar Sesión</button>
) : (
<button>Iniciar Sesión</button>
)}
</div>
);
}
Si el bloque de código es grande, usad paréntesis () después del ? y del : para poder indentar el JSX en varias líneas y mejorar la legibilidad.
El Operador AND &&
A veces no queremos mostrar “esto o esto”. A veces solo queremos mostrar un componente si la condición es verdadera, y si no, no mostrar nada.
Podríamos usar un ternario devolviendo null (condicion ? <Algo/> : null), pero es bastante sucio.
Para esto, es muy común aprovechar el comportamiento de cortocircuito del operador lógico AND (&&).
Esto se aprovecha de que, en JavaScript,
true && expresionevalúa aexpresionfalse && expresionevalúa afalse.
React es lo suficientemente listo para no renderizar nada si recibe un false, null o undefined, así que podemos usarlo como render condicional.
function Mensajes({ nuevosMensajes }) {
return (
<div>
<h1>Buzón de entrada</h1>
{/* Solo se muestra si hay mensajes */}
{nuevosMensajes.length > 0 && (
<span className="badge">
Tienes mensajes sin leer
</span>
)}
</div>
);
}
Control de flujo con IF
Hemos dicho que no se puede usar if dentro del JSX. Pero sí podemos usarlo antes del return.
Por ejemplo, a veces queremos evitar renderizar el componente entero si falta algo. En estos casos, usamos if normales para cortar la ejecución. Esto se conoce como patrón de Early Return.
function PerfilUsuario({ usuario, isLoading }) {
// 1. Si está cargando, devolvemos esto y terminamos
if (isLoading) {
return <div>Cargando perfil...</div>;
}
// 2. Si no hay usuario (es null), devolvemos error o nada
if (!usuario) {
return null; // Renderizar null hace que no se pinte nada en el DOM
}
// 3. Si llegamos aquí, tenemos datos y no estamos cargando
return (
<div className="perfil">
<h1>{usuario.nombre}</h1>
<p>{usuario.bio}</p>
</div>
);
}
Este patrón hace que el JSX final (return (...)) quede más limpio, sobre todo si la alternativa era anidar ternarios en esxceso.
Funciones de renderizado
Si necesitas una parte lógica compleja pero solo para una pequeña parte del componente (no para todo), la opción anterior no te podría obligar a duplicar mucho código. Mientras que los ternarios que habíamos visto, tienen a volverse ilegible si anidamos muchas.
Aquí la mejor práctica es extraer esa lógica a una función auxiliar. Al ser una función de JavaScript normal (fuera del JSX, de las {}), aquí sí podemos usar if, else o switch con normalidad.
function EstadoPedido({ estado }) {
const renderIcono = () => {
switch(estado) {
case 'enviado': return <IconoCamion />;
case 'entregado': return <IconoCheck />;
case 'cancelado': return <IconoCruz />;
default: return <IconoReloj />;
}
};
return (
<div className="tarjeta-pedido">
{/* Llamamos a la función para obtener el JSX resultante */}
{renderIcono()}
<span>Estado: {estado}</span>
</div>
);
}
Aunque funciona, puede que sea preferible crear sub-componentes (<IconoPedido estado={estado} />) para mantener el componente principal limpio. Pero es una herramienta útil, depende del caso.
