Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

211
Vistas
¿Por qué mi useEffect se ejecuta infinitamente cuando se rechaza la promesa, pero solo una vez cuando se cumple?

Estoy tratando de obtener datos de un backend simulado creado con el servidor JSON con la ayuda de Axios. Ahora, cuando el estado de respuesta es 200, es decir, los datos se obtuvieron con éxito, el estado de mi variable de éxito cambia a verdadero. El useEffect se ejecuta solo una vez y el mensaje brinda solo aparece una vez. Pero ahora, cuando hay un error al obtener los datos, useEffect se ejecuta infinitamente y el brindis comienza a aparecer sin parar uno tras otro. ¿Alguien puede explicarme por qué sucede esto y cómo puedo resolver este problema?

A continuación se muestra el código que he escrito.

 import React, { useState, useEffect } from 'react'; import Loader from './../components/Loader'; import axios from 'axios'; import { toast } from 'react-toastify'; const PostsTD = () => { const [posts, setPosts] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState({ status: false, message: '', }); const [success, setSuccess] = useState(false); const getPosts = () => { axios .get('http://localhost:5050/posts') .then((res) => { setPosts(res.data); setLoading(false); if (res.status === 200) setSuccess(true); }) .catch((error) => { setLoading(false); setError({ status: true, message: error.message }); }); }; useEffect(() => { getPosts(); if (error.status) { toast.error(error.message); } if (success) toast.success('Success!'); }, [success, error]); if (loading) { return ( <div className="px-28 text-center py-12"> <Loader /> </div> ); } return ( <div className="md:px-28 px-6"> <h1 className="text-center font-extrabold text-gray-400 my-4 text-4xl">POSTS FETCHED USING AXIOS</h1> {posts && posts?.length > 0 ? ( <div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-3 py-2 px-3 bg-red-500"> {posts?.map((post, idx) => { return ( <div key={idx} className="p-3 bg-red-200 text-gray-900 rounded-md"> <h2 className="font-semibold text-xl">{post.title}</h2> <p className="font-normal my-3">{post.body}</p> </div> ); })} </div> ) : ( <h1>NO posts to render</h1> )} </div> ); }; export default PostsTD;
about 4 years ago · Juan Pablo Isaza
3 Respuestas
Responde la pregunta

0

 useEffect(() => { getPosts(); if (error.status) { toast.error(error.message); } if (success) toast.success('Success!'); }, [success, error]);

Dado que el error está en la matriz de dependencias, cada vez que cambie el error, este efecto se ejecutará. Entonces, el error cambia, lo que hace que obtenga las publicaciones, lo que hace que el error cambie, etc.

Dividiría esto en efectos separados; uno para dar inicio a la carga, y otro para hacer los brindis:

 useEffect(() => { getPosts(); }, []); useEffect(() => { if (error.status) { toast.error(error.message); } if (success) toast.success('Success!'); }, [sucess, error]);
about 4 years ago · Juan Pablo Isaza Denunciar

0

Como otros han mencionado antes, su problema es que su useEffect desencadena otra llamada getPosts cuando se suponía que solo reaccionaría a un cambio en las variables de éxito o error.

Cuando realice llamadas a la API dentro de un efecto, tenga en cuenta lo siguiente: (el número 1 se basa en una opinión personal)

  1. Preferiblemente maneje la promesa dentro del efecto (o haga 2 efectos separados: 1 para hacer la llamada y 1 para reaccionar al éxito/error)
  2. Agregue una función de limpieza para manejar la cancelación de la promesa en caso de una limpieza ( https://beta.reactjs.org/learn/synchronizing-with-effects#fetching-data )

Así es como probablemente lo estructuraría:

 useEffect(() => { const controller = new AbortController(); axios .get('http://localhost:5050/posts', { signal: controller.signal }) .then((res) => { setPosts(res.data); setLoading(false); if (res.status === 200) setSuccess(true); }) .catch((error) => { setLoading(false); setError({ status: true, message: error.message }); }); return () => { controller.abort(); } }, []);
about 4 years ago · Juan Pablo Isaza Denunciar

0

Su useEffect tiene un error como dependencia y getPosts en su lógica, por lo tanto, si getPosts establece un error (como lo hace), crea un bucle infinito.

useEffect => getPosts => setError => useEffect ...

Puede resolver esto eliminando la dependencia de error de su useEffect, si aún desea recuperar datos, creo que debería llamar directamente a getPosts en getPosts en un setTimeout, por ejemplo.

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda