21. Pasando State con Datos

 

Tutorial 21: Pasando State con Datos

馃摝 Introducci贸n al manejo de estado

Ahora que tenemos los datos de la API, necesitamos almacenarlos en el estado de React para poder:

  • ✅ Mantener los datos entre renderizados

  • ✅ Actualizar la UI cuando cambien los datos

  • ✅ Pasar los datos a otros componentes

  • ✅ Reaccionar a cambios en los datos

馃幆 Paso 1: Importar useState

Primero, necesitamos importar el hook useState de React:

javascript

// En la parte superior de tu App.js, a帽ade:

import { useState } from "react";

// Aseg煤rate de que est谩 al inicio del archivo, junto con los otros imports

Tu archivo deber铆a verse as铆 ahora:

javascript

import './App.css';

import imageRickMorty from "./img/rick-morty.png";

import { useState } from "react";  // ← ¡Nuevo import!

馃敡 Paso 2: Crear el estado para los personajes

Dentro de tu componente App, justo antes de la funci贸n reqApi, crea el estado:

javascript

function App() {

  // Estado para almacenar los personajes

  const [characters, setCharacters] = useState(null);

  

  // Tu funci贸n reqApi sigue aqu铆...

  const reqApi = async () => {

    // ...

  };

  

  return (

    // ...

  );

}

Explicaci贸n del c贸digo:

  • characters: Variable que contiene el valor actual del estado

  • setCharacters: Funci贸n para actualizar el estado

  • useState(null): Inicializamos el estado con null (vac铆o al inicio)

馃攳 Paso 3: Verificar el estado inicial

Vamos a hacer un console.log para ver el estado inicial:

javascript

function App() {

  const [characters, setCharacters] = useState(null);

  

  // Ver estado inicial

  console.log("Estado inicial de characters:", characters);

  

  const reqApi = async () => {

    // ...

  };

  

  return (

    // ...

  );

}

Deber铆as ver en consola: Estado inicial de characters: null

馃殌 Paso 4: Actualizar el estado con los datos de la API

Modifica tu funci贸n reqApi para que actualice el estado:

javascript

const reqApi = async () => {

  try {

    // 1. Hacer la petici贸n

    const api = await fetch("https://rickandmortyapi.com/api/character");

    

    // 2. Verificar respuesta

    if (!api.ok) {

      throw new Error(`Error: ${api.status}`);

    }

    

    // 3. Convertir a JSON

    const charactersApi = await api.json();

    

    // 4. Actualizar el estado con los personajes

    setCharacters(charactersApi.results);

    

    // 5. Verificar en consola

    console.log("Estado actualizado con:", charactersApi.results.length, "personajes");

    

  } catch (error) {

    console.error("Error:", error);

  }

};

馃憗️ Paso 5: Verificar que el estado se actualiza

Vamos a agregar un console.log para ver cuando cambia el estado:

javascript

function App() {

  const [characters, setCharacters] = useState(null);

  

  // Este console.log se ejecuta en cada render

  console.log("Valor actual de characters:", characters);

  console.log("¿Tenemos personajes?:", characters ? "S铆" : "No");

  console.log("Cantidad de personajes:", characters ? characters.length : 0);

  

  const reqApi = async () => {

    // ... funci贸n anterior

  };

  

  return (

    // ...

  );

}

馃И Paso 6: Probar la actualizaci贸n

  1. Abre tu aplicaci贸n en el navegador

  2. Abre la consola (F12)

  3. Observa el estado inicial:

  4. text

Valor actual de characters: null

¿Tenemos personajes?: No

  1. Cantidad de personajes: 0

  2. Haz clic en "Buscar personajes"

  3. Deber铆as ver:

  4. text

Valor actual de characters: (20) [{...}, {...}, ...]

¿Tenemos personajes?: S铆

  1. Cantidad de personajes: 20

馃搳 Paso 7: Examinar los datos en el estado

Agrega un console.log m谩s detallado despu茅s de actualizar el estado:

javascript

const reqApi = async () => {

  try {

    const api = await fetch("https://rickandmortyapi.com/api/character");

    const charactersApi = await api.json();

    

    // Actualizar estado

    setCharacters(charactersApi.results);

    

    // Datos detallados

    console.log("=== DATOS OBTENIDOS ===");

    console.log("Total en API:", charactersApi.info.count);

    console.log("Obtenidos:", charactersApi.results.length);

    console.log("Primer personaje:", charactersApi.results[0].name);

    console.log("Array completo:", charactersApi.results);

    

  } catch (error) {

    console.error("Error:", error);

  }

};

馃攧 Paso 8: Renderizado condicional basado en el estado

Vamos a modificar el JSX para mostrar diferentes cosas seg煤n el estado:

javascript

return (

  <div className="App">

    <header className="App-header">

      <h1 className="title">Rick & Morty</h1>

      

      {/* Renderizado condicional */}

      {characters ? (

        <div>

          <h2>Personajes cargados: {characters.length}</h2>

          <p>Aqu铆 ir谩 la lista de personajes...</p>

        </div>

      ) : (

        <>

          <img 

            src={imageRickMorty} 

            alt="Rick & Morty" 

            className="img-home" 

          />

          <button onClick={reqApi} className="btn-search">

            Buscar personajes

          </button>

        </>

      )}

    </header>

  </div>

);

Explicaci贸n del renderizado condicional:

  • Si characters tiene valor (no es null): Muestra la lista de personajes

  • Si characters es null: Muestra la imagen y el bot贸n

馃帹 Paso 9: Mejorar la visualizaci贸n temporal

Vamos a mostrar algo m谩s 煤til mientras creamos el componente real:

javascript

return (

  <div className="App">

    <header className="App-header">

      <h1 className="title">Rick & Morty</h1>

      

      {characters ? (

        <div>

          <h2>¡Personajes cargados!</h2>

          <p>Total: {characters.length} personajes</p>

          

          {/* Mostrar primeros 3 personajes como prueba */}

          <div style={{ textAlign: 'left', marginTop: '20px' }}>

            <h3>Primeros 3 personajes:</h3>

            {characters.slice(0, 3).map((character, index) => (

              <div key={index} style={{ marginBottom: '10px' }}>

                <strong>{character.name}</strong>

                <br />

                Estado: {character.status} | Especie: {character.species}

                <br />

                Episodios: {character.episode.length}

              </div>

            ))}

          </div>

          

          <button 

            onClick={() => setCharacters(null)} 

            style={{ marginTop: '20px', padding: '10px 20px' }}

          >

            Volver al inicio

          </button>

        </div>

      ) : (

        <>

          <img src={imageRickMorty} alt="Rick & Morty" className="img-home" />

          <button onClick={reqApi} className="btn-search">

            Buscar personajes

          </button>

        </>

      )}

    </header>

  </div>

);

馃摑 C贸digo completo hasta ahora:

javascript

import './App.css';

import imageRickMorty from "./img/rick-morty.png";

import { useState } from "react";


function App() {

  // 1. Estado para almacenar los personajes

  const [characters, setCharacters] = useState(null);

  

  // 2. Funci贸n para obtener datos de la API

  const reqApi = async () => {

    try {

      console.log("Obteniendo personajes...");

      

      const api = await fetch("https://rickandmortyapi.com/api/character");

      

      if (!api.ok) {

        throw new Error(`Error HTTP: ${api.status}`);

      }

      

      const charactersApi = await api.json();

      

      // 3. Actualizar estado con los personajes

      setCharacters(charactersApi.results);

      

      console.log("✅ Estado actualizado con", charactersApi.results.length, "personajes");

      

    } catch (error) {

      console.error("❌ Error:", error);

      alert("No se pudieron cargar los personajes. Intenta nuevamente.");

    }

  };

  

  // 4. Renderizado condicional basado en el estado

  return (

    <div className="App">

      <header className="App-header">

        <h1 className="title">Rick & Morty</h1>

        

        {characters ? (

          // Cuando hay personajes

          <div>

            <h2>¡{characters.length} Personajes Encontrados!</h2>

            <p>Pronto mostraremos todos los personajes aqu铆...</p>

            

            {/* Bot贸n para volver */}

            <button 

              onClick={() => setCharacters(null)}

              className="btn-search"

              style={{ marginTop: '20px' }}

            >

              ← Volver al inicio

            </button>

          </div>

        ) : (

          // Cuando no hay personajes (estado inicial)

          <>

            <img 

              src={imageRickMorty} 

              alt="Rick & Morty" 

              className="img-home" 

            />

            <button 

              onClick={reqApi} 

              className="btn-search"

            >

              Buscar personajes

            </button>

          </>

        )}

      </header>

    </div>

  );

}


export default App;

馃攳 Paso 10: Verificaci贸n final

Prueba estos escenarios:

  1. Carga inicial:

    • Solo imagen y bot贸n

    • Estado: characters = null

  2. Despu茅s de hacer clic:

    • Muestra mensaje de personajes cargados

    • Estado: characters = array con 20 objetos

  3. Volver al inicio:

    • Al hacer clic en "Volver", se restablece characters a null

    • Vuelve a mostrar imagen y bot贸n

馃幆 ¿Qu茅 hemos logrado?

✅ Importamos y usamos useState
✅ Creamos estado para almacenar personajes
✅ Actualizamos el estado con datos reales de API
✅ Implementamos renderizado condicional
✅ Creamos flujo completo: carga → muestra → vuelta

馃挕 Conceptos importantes aprendidos:

  1. Estado de React: Almacena datos que pueden cambiar

  2. Hook useState: const [valor, setValor] = useState(inicial)

  3. Actualizaci贸n de estado: setValor(nuevoValor) causa re-render

  4. Renderizado condicional: {condicion ? verdadero : falso}

  5. Prop drilling (pr贸ximo paso): Pasar estado a componentes hijos

馃殌 Pr贸ximo paso: Componente Characters

En el siguiente tutorial vamos a:

  1. Crear un nuevo componente Characters.js

  2. Pasar el estado como props a este componente

  3. Mostrar todos los personajes de forma organizada

  4. Estilizar las tarjetas de cada personaje


馃И Actividad pr谩ctica

Modifica tu c贸digo para:

  1. Mostrar un contador de personajes vivos vs muertos

  2. Agregar un bot贸n que muestre solo personajes humanos

  3. Implementar un loader mientras se cargan los datos

javascript

// Ejemplo de loader b谩sico

const [loading, setLoading] = useState(false);


const reqApi = async () => {

  setLoading(true);

  try {

    // ... petici贸n a API

  } catch (error) {

    // ... manejo de error

  } finally {

    setLoading(false);

  }

};


// En el render:

{loading ? <p>Cargando...</p> : (/* contenido normal */)}

¿Lograste ver los 20 personajes en el estado de React? ¡Comparte tu progreso! 馃専


¿Tienes preguntas sobre c贸mo funciona el estado en React? ¡Este es el momento perfecto para aclararlas


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