Search code examples
javascriptreactjserror-handlingfetchtoast

Why do my fetch request causes an infinite error loop in ReactJs using React Toast Notifications


I want to get a toast notification every time I catch an error in the fetch function.I am using a loop inside a component before the return to fetch data about different cities with accuweather api.

This is my handle errors function:

export const handleErrors = (response) => {
if (!response.ok) {
    return Promise.reject(response.statusText);
}
return response;}

This is my component that fetches the data:

import { useToasts } from 'react-toast-notifications';
import handleErrors from '../../handleErrors.js';

const mapStateToProps = state => ({
favorites:state.favorites.favorites})

export const Favorites = (props) => {

const { addToast } = useToasts();
let data = null;

props.favorites.map((city,i) => {
fetch(`http://dataservice.accuweather.com/currentconditions/v1/${city.CityKey}?apikey=${apiKey}`)
 .then(handleErrors)
 .then(response => response.json())
 .then(res => {data = [...data,res[0]];console.log(data)})
 .catch(error => addToast(error.message, { appearance: 'error' }))
});

return(
  <div>
    {data === null ? null : data.map((city,i => {
      return(<FavoriteTile
              city={city}
              key={i}/>
            )
  </div>
)
}

Now when trying to load the component page Im getting infinite toast errors and the page crashes.


Solution

  • if you're using functional components just wrap your fetch function with useEffect.

    What's happening now is every-time you fetch something from that api your toast is updating hence component is being rerendered and calling fetch again in an infinite loop.

    useEffect(() => {
      props.favorites.map((city,i) => {
        fetch(`http://dataservice.accuweather.com/currentconditions/v1/${city.CityKey}? 
        apikey=${apiKey}`)
        .then(handleErrors)
        .then(response => response.json())
        .then(res => {data = [...data,res[0]];console.log(data)})
        .catch(error => addToast(error.message, { appearance: 'error' }))
      });
    }, [])