23. Aplicando Ternarios
Tutorial 23: Aplicando Ternarios
馃幆 Introducci贸n a los operadores ternarios en React
Los operadores ternarios son una forma concisa de hacer renderizado condicional en React. En este tutorial vamos a implementarlos para mostrar diferentes componentes seg煤n el estado de nuestra aplicaci贸n.
馃敡 Paso 1: Entendiendo el flujo actual
Primero, veamos c贸mo est谩 funcionando nuestro c贸digo actualmente:
javascript
// En App.js
const [characters, setCharacters] = useState(null);
// Cuando hacemos clic en el bot贸n:
const reqApi = async () => {
const api = await fetch("https://rickandmortyapi.com/api/character");
const charactersApi = await api.json();
setCharacters(charactersApi.results); // ← Esto actualiza el estado
};
Estado inicial: characters = null
Despu茅s del clic: characters = array con 20 objetos
馃帾 Paso 2: Implementando el operador ternario
Vamos a modificar el JSX en App.js para usar un operador ternario:
javascript
// REEMPLAZA el return actual con esto:
return (
<div className="App">
<header className="App-header">
<h1 className="title">Rick & Morty</h1>
{/* OPERADOR TERNARIO */}
{characters ? (
// Si characters TIENE valor (no es null/undefined/false)
<Characters characters={characters} />
) : (
// Si characters NO tiene valor (es null/undefined/false)
<>
<img
src={imageRickMorty}
alt="Rick & Morty"
className="img-home"
/>
<button onClick={reqApi} className="btn-search">
Buscar personajes
</button>
</>
)}
</header>
</div>
);
馃摉 Explicaci贸n del operador ternario:
javascript
{condicion ? (si_verdadero) : (si_falso)}
En nuestro caso:
Condici贸n: characters (si tiene valor truthy)
Si verdadero: <Characters characters={characters} />
Si falso: <> ... </> (Fragment con imagen y bot贸n)
馃攳 Paso 3: Verificando en Characters.js
Vamos a verificar que nuestro componente est谩 recibiendo los props correctamente:
javascript
// En Characters.js
import React from "react";
export default function Characters(props) {
// 1. Hacer console.log para verificar
console.log("Props recibidas:", props);
console.log("Characters recibidos:", props.characters);
console.log("Cantidad de personajes:", props.characters ? props.characters.length : 0);
// 2. Extraer los characters de las props
const { characters } = props;
return (
<div>
<h1>Personajes</h1>
<p>Total: {characters.length} personajes cargados</p>
</div>
);
}
馃洜️ Paso 4: Solucionar posibles errores
Si recibes un error como "Cannot read properties of null", aseg煤rate de que el componente solo se renderice cuando characters tenga valor:
javascript
// MEJORA: Validaci贸n segura
export default function Characters(props) {
const { characters } = props;
// Validar que characters exista
if (!characters) {
return <div>Cargando personajes...</div>;
}
// Si llegamos aqu铆, characters existe
return (
<div>
<h1>Personajes</h1>
<p>Total: {characters.length} personajes</p>
{/* Resto del c贸digo */}
</div>
);
}
馃攧 Paso 5: Pasar tambi茅n setCharacters
Necesitamos pasar la funci贸n para resetear el estado y poder volver al inicio:
javascript
// En App.js, actualiza el ternario:
{characters ? (
<Characters
characters={characters}
setCharacters={setCharacters}
/>
) : (
// ... resto igual
)}
馃彔 Paso 6: Agregar funcionalidad para volver
Ahora en Characters.js, podemos agregar un bot贸n para volver:
javascript
export default function Characters(props) {
const { characters, setCharacters } = props;
// Funci贸n para resetear y volver al inicio
const resetCharacters = () => {
setCharacters(null);
};
// Validaci贸n
if (!characters) {
return <div>Cargando...</div>;
}
return (
<div className="characters">
<h1>Personajes</h1>
{/* Bot贸n para volver */}
<button onClick={resetCharacters} className="btn-search">
← Volver al inicio
</button>
{/* Mostrar algunos datos */}
<div>
<h3>Primeros 3 personajes:</h3>
{characters.slice(0, 3).map((character, index) => (
<div key={index}>
<h4>{character.name}</h4>
<p>Estado: {character.status}</p>
</div>
))}
</div>
{/* Otro bot贸n para volver al final */}
<button onClick={resetCharacters} className="btn-search">
← Volver al inicio
</button>
</div>
);
}
馃帹 Paso 7: Mejorar la visualizaci贸n
Vamos a mostrar todos los personajes de forma organizada:
javascript
export default function Characters(props) {
const { characters, setCharacters } = props;
const resetCharacters = () => {
setCharacters(null);
};
if (!characters) {
return <div>Cargando personajes...</div>;
}
return (
<div className="characters">
<h1>Personajes ({characters.length})</h1>
<button onClick={resetCharacters} className="btn-search">
← Volver a la Home
</button>
{/* Grid de personajes */}
<div style={{
display: 'grid',
gridTemplateColumns: 'repeat(auto-fill, minmax(250px, 1fr))',
gap: '20px',
marginTop: '30px',
width: '100%'
}}>
{characters.map((character, index) => (
<div
key={index}
style={{
background: '#3c3e44',
borderRadius: '10px',
padding: '15px',
color: 'white',
textAlign: 'left'
}}
>
<h3 style={{ marginTop: 0 }}>{character.name}</h3>
<p><strong>Estado:</strong> {character.status}</p>
<p><strong>Especie:</strong> {character.species}</p>
<p><strong>Episodios:</strong> {character.episode.length}</p>
<p><strong>G茅nero:</strong> {character.gender}</p>
<p><strong>Origen:</strong> {character.origin.name}</p>
</div>
))}
</div>
<button
onClick={resetCharacters}
className="btn-search"
style={{ marginTop: '30px' }}
>
← Volver a la Home
</button>
</div>
);
}
馃敡 Paso 8: Usar React Developer Tools
Para depurar y verificar que todo funciona correctamente:
Instala React Developer Tools (extensi贸n del navegador)
Abre las herramientas de desarrollo (F12)
Ve a la pesta帽a "Components"
Busca tu componente App
Deber铆as ver:
characters en el estado (null inicialmente)
Characters como componente hijo cuando se activa
馃摑 C贸digo completo de App.js:
javascript
import './App.css';
import imageRickMorty from "./img/rick-morty.png";
import { useState } from "react";
import Characters from "./Components/Characters";
function App() {
const [characters, setCharacters] = useState(null);
const reqApi = async () => {
try {
const api = await fetch("https://rickandmortyapi.com/api/character");
if (!api.ok) {
throw new Error(`Error: ${api.status}`);
}
const charactersApi = await api.json();
setCharacters(charactersApi.results);
} catch (error) {
console.error("Error al cargar personajes:", error);
alert("Hubo un problema al cargar los personajes");
}
};
return (
<div className="App">
<header className="App-header">
<h1 className="title">Rick & Morty</h1>
{/*
OPERADOR TERNARIO PARA RENDERIZADO CONDICIONAL
Si characters tiene valor → muestra Characters
Si characters es null → muestra Home
*/}
{characters ? (
<Characters
characters={characters}
setCharacters={setCharacters}
/>
) : (
// Fragmento React (<> </>) para agrupar m煤ltiples elementos
<>
<img
src={imageRickMorty}
alt="Rick & Morty"
className="img-home"
/>
<button onClick={reqApi} className="btn-search">
Buscar personajes
</button>
</>
)}
</header>
</div>
);
}
export default App;
馃摑 C贸digo completo de Characters.js:
javascript
import React from "react";
export default function Characters(props) {
// Destructuring de props
const { characters, setCharacters } = props;
// Funci贸n para resetear el estado
const resetCharacters = () => {
setCharacters(null);
};
// Validaci贸n: si no hay characters, mostrar mensaje
if (!characters || characters.length === 0) {
return (
<div>
<h2>No hay personajes para mostrar</h2>
<button onClick={resetCharacters} className="btn-search">
← Volver al inicio
</button>
</div>
);
}
return (
<div className="characters">
<h1>Personajes de Rick & Morty</h1>
{/* Encabezado con bot贸n para volver */}
<div style={{ marginBottom: '20px' }}>
<button onClick={resetCharacters} className="btn-search">
← Volver al inicio
</button>
<span style={{ marginLeft: '20px' }}>
Mostrando {characters.length} personajes
</span>
</div>
{/* Grid de personajes */}
<div className="characters-grid">
{characters.map((character, index) => (
<div className="character-card" key={index}>
<h3>{character.name}</h3>
<div className="character-info">
<p><span className="label">Estado:</span> {character.status}</p>
<p><span className="label">Especie:</span> {character.species}</p>
<p><span className="label">Episodios:</span> {character.episode.length}</p>
<p><span className="label">G茅nero:</span> {character.gender}</p>
</div>
</div>
))}
</div>
{/* Pie de p谩gina con bot贸n para volver */}
<div style={{ marginTop: '30px' }}>
<button onClick={resetCharacters} className="btn-search">
← Volver al inicio
</button>
</div>
</div>
);
}
馃帹 Paso 9: Agregar estilos CSS
A帽ade estos estilos a tu index.css:
css
/* Estilos para el componente Characters */
.characters {
width: 100%;
max-width: 1200px;
padding: 20px;
}
.characters-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 20px;
margin-top: 20px;
}
.character-card {
background: #3c3e44;
border-radius: 10px;
padding: 20px;
color: white;
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.character-card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.3);
}
.character-card h3 {
margin-top: 0;
color: #61dafb;
border-bottom: 2px solid #61dafb;
padding-bottom: 10px;
}
.character-info {
font-size: 14px;
}
.character-info .label {
color: #9e9e9e;
font-weight: bold;
}
/* Responsive */
@media (max-width: 768px) {
.characters-grid {
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
}
}
@media (max-width: 480px) {
.characters-grid {
grid-template-columns: 1fr;
}
}
馃И Paso 10: Probar el flujo completo
Prueba estos escenarios:
Carga inicial:
Deber铆as ver solo la imagen y el bot贸n
Estado: characters = null
Despu茅s de hacer clic:
Deber铆as ver la lista de personajes
Estado: characters = array con 20 objetos
Haz clic en "Volver al inicio":
Deber铆as regresar a la p谩gina inicial
Estado: characters = null nuevamente
Verifica en consola:
Los console.log deber铆an mostrar la informaci贸n correcta
馃幆 ¿Qu茅 hemos aprendido?
✅ Operadores ternarios para renderizado condicional
✅ Pasar props entre componentes padre e hijo
✅ Fragmentos React (<> </>) para agrupar elementos
✅ Validaci贸n de datos antes de renderizar
✅ Flujo bidireccional entre componentes
✅ Uso de React Developer Tools para depuraci贸n
馃殌 Pr贸ximo paso: Mostrar im谩genes y mejorar UI
En el siguiente tutorial vamos a:
Mostrar las im谩genes de cada personaje
Agregar indicadores visuales de estado (vivo/muerto)
Mejorar el dise帽o con CSS Grid
Hacer el componente responsive
馃挕 Actividad pr谩ctica
Modifica tu c贸digo para:
Mostrar un mensaje diferente si hay exactamente 20 personajes vs menos
Agregar un bot贸n que ordene los personajes alfab茅ticamente
Implementar un buscador simple por nombre
javascript
// Ejemplo: Mensaje condicional
{characters.length === 20 ? (
<p>Mostrando todos los personajes de la primera p谩gina</p>
) : (
<p>Mostrando {characters.length} personajes filtrados</p>
)}
¿Cu谩ntos personajes con status "Alive" vs "Dead" hay en tu lista? ¡Comp谩rtelo! 馃専
¿Tienes dudas sobre c贸mo funcionan los operadores ternarios o los fragments? ¡Pregunta en los comentarios
Comentarios
Publicar un comentario