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:

  1. Instala React Developer Tools (extensi贸n del navegador)

  2. Abre las herramientas de desarrollo (F12)

  3. Ve a la pesta帽a "Components"

  4. Busca tu componente App

  5. 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:

  1. Carga inicial:

    • Deber铆as ver solo la imagen y el bot贸n

    • Estado: characters = null

  2. Despu茅s de hacer clic:

    • Deber铆as ver la lista de personajes

    • Estado: characters = array con 20 objetos

  3. Haz clic en "Volver al inicio":

    • Deber铆as regresar a la p谩gina inicial

    • Estado: characters = null nuevamente

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

  1. Mostrar las im谩genes de cada personaje

  2. Agregar indicadores visuales de estado (vivo/muerto)

  3. Mejorar el dise帽o con CSS Grid

  4. Hacer el componente responsive


馃挕 Actividad pr谩ctica

Modifica tu c贸digo para:

  1. Mostrar un mensaje diferente si hay exactamente 20 personajes vs menos

  2. Agregar un bot贸n que ordene los personajes alfab茅ticamente

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

Entradas m谩s populares de este blog

9.3-Tutorial de Componentes React con Props -SSS

9.6-Ciclo de Vida de un Componente React

9-Componentes en React-estado