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
Abre tu aplicaci贸n en el navegador
Abre la consola (F12)
Observa el estado inicial:
text
Valor actual de characters: null
¿Tenemos personajes?: No
Cantidad de personajes: 0
Haz clic en "Buscar personajes"
Deber铆as ver:
text
Valor actual de characters: (20) [{...}, {...}, ...]
¿Tenemos personajes?: S铆
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:
Carga inicial:
Solo imagen y bot贸n
Estado: characters = null
Despu茅s de hacer clic:
Muestra mensaje de personajes cargados
Estado: characters = array con 20 objetos
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:
Estado de React: Almacena datos que pueden cambiar
Hook useState: const [valor, setValor] = useState(inicial)
Actualizaci贸n de estado: setValor(nuevoValor) causa re-render
Renderizado condicional: {condicion ? verdadero : falso}
Prop drilling (pr贸ximo paso): Pasar estado a componentes hijos
馃殌 Pr贸ximo paso: Componente Characters
En el siguiente tutorial vamos a:
Crear un nuevo componente Characters.js
Pasar el estado como props a este componente
Mostrar todos los personajes de forma organizada
Estilizar las tarjetas de cada personaje
馃И Actividad pr谩ctica
Modifica tu c贸digo para:
Mostrar un contador de personajes vivos vs muertos
Agregar un bot贸n que muestre solo personajes humanos
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
Publicar un comentario