Cada vez que obtengo datos en mi página, después de unos segundos, toda mi aplicación de reacción desaparece ya que en el div raíz en el html se deja completamente vacío como este <div id="root"></div> como si no hubiera nada. Esto también está sucediendo en todos mis otros proyectos, incluso cuando creo uno nuevo, esta desaparición de la reacción sigue ocurriendo a veces, incluso sin agregar ninguna lógica, se niega a representar html sin formato. Los errores que recibo por ahora en este proyecto actual en la consola es este
caracteres.mapa no es una función
No sé qué podría estar causando esto, pero mi código se ve así por ahora, comenzando con el archivo App.js. Estoy extrayendo datos de una API.
import {BrowserRouter, Route, Routes} from "react-router-dom" import Home from "./components/Home"; function App() { return ( <div className="App"> <BrowserRouter> <Routes> <Route path="/" element={<Home />} /> </Routes> </BrowserRouter> </div> ); } export default App;Y luego, seguido de la página CharactersListing, que se supone que muestra todos los personajes del programa.
import React, {useEffect, useState} from 'react' import CharacterCard from './CharacterCard' export default function BadListings() { const [characters, setCharacters] = useState([]) useEffect(() => { const getData = async () => { await fetch("https://www.breakingbadapi.com/api/characters") .then(response => { setCharacters(response.json()); console.log(characters); }) .catch(err => console.log("There must have been an error somewhere in your code", err.message)); } getData(); }); return ( <div className='container'> {characters.map(character => ( <div> <CharacterCard name={character.name} status={character.status} image={character.img} /> </div> ))} </div> ) }Y finalmente, el CharacterCard.js
import React from 'react' import "../styles/styles.css" export default function CharacterCard({name, status, image}) { return ( <div className='card'> <h1>{name}</h1> <h2>{status}</h2> <img src={image} alt="umfanekiso" className='imgur' /> </div> ) }No sé qué podría estar causando esto. Nunca he tenido este problema, acaba de comenzar hoy. ¿Qué podría estar causándolo?
El problema es que no estás configurando el estado de los characters en lo que crees que es. response.json() devuelve un objeto Promise y no tiene una propiedad de map que sea una función para llamar.
Al useEffect también le falta una dependencia, por lo que cualquier cosa que desencadene este componente BadListings para que se reproduzca también volverá a activar este useEffect , que actualiza el estado y activa otro procesamiento. Es probable que el código se reproduzca en bucle.
response.json() se resuelva y pase ese valor de resultado a la función de actualización del estado de los characters . Tenga en cuenta que también he reescrito la lógica para usar async/await con try/catch , ya que generalmente se considera antipatrón mezclar async/await con las cadenas Promise.useEffect . Como no veo ninguna dependencia, use una matriz vacía para que el efecto se ejecute solo una vez cuando se monta el componente.Cadena de promesa Ejemplo:
useEffect(() => { fetch("https://www.breakingbadapi.com/api/characters") .then(response => response.json()) // <-- wait for Promise to resolve .then(characters => setCharacters(characters) .catch(err => { console.log("There must have been an error somewhere in your code", err.message) }); }, []); // <-- add empty dependency array async/await Ejemplo:
useEffect(() => { const getData = async () => { try { const response = await fetch("https://www.breakingbadapi.com/api/characters"); const characters = await response.json(); // <-- wait for Promise to resolve setCharacters(characters); } catch(err) { console.log("There must have been an error somewhere in your code", err?.message); }; } getData(); }, []); // <-- add empty dependency arrayNo olvide agregar una tecla React a los caracteres asignados:
{characters.map((character) => ( <div key={character.char_id}> // <-- Add React key to outer element <CharacterCard name={character.name} status={character.status} image={character.img} /> </div> ))}Los characters son una cadena y las cadenas no tienen el método .map() , es por eso que React falla. Y dado que React se bloqueó, no pudo montar el HTML generado en #root .
Puede usar [...strings] para usar el método .map() .
Gran instinto para buscar errores en la consola.
La respuesta de Umut Gerçek es correcta, pero agregaría una sugerencia adicional: si va a map algo, debe instanciarlo en el estado como algo que se puede mapear. Establezca su estado inicial en una matriz:
const [characters, setCharacters] = useState([]) Tenga en cuenta la 'C' mayúscula en el setter; esa es la convención useState .
Luego configure los caracteres como lo está haciendo actualmente:
setCharacters(response.json()); Y su mapa debería funcionar independientemente del resultado de su fetch y manejar múltiples elementos también.