Basically I have a function called getWeatherForecast which gets some weather data from an api however, I am getting an infinite loop and it keeps requesting for the data an infinite number of times.
Here is my function
const getWeatherForecast = async () => {
const weatherForecast = await axios.get(`${API_ENDPOINT}lat=${props.latitude}&lon=${props.longitude}&exclude=hourly,daily&appid=${API_KEY}`)
console.log(weatherForecast)
setWeatherDetails(weatherForecast)
}
This is how I used the useEffect
useEffect(() => {
getWeatherForecast()
// console.log(`This is the forecast ${weatherDetails}`)
} , [getWeatherForecast])
Any idea why I am getting an infinite loop ?
CodePudding user response:
Because this:
getWeatherForecast
is a function which gets recreated on each render.
Inside that function you are calling a setWeatherDetails
, which triggers a render. Hence on the next render a new instance of that function is created, which is different from the previous one, and useEffect
is called again.
Wrap that function in useCallback.
let getWeatherForecast = React.useCallback(async () => {
const weatherForecast = await axios.get(
`${API_ENDPOINT}lat=${props.latitude}&lon=${props.longitude}&exclude=hourly,daily&appid=${API_KEY}`
);
console.log(weatherForecast);
setWeatherDetails(weatherForecast);
}, [
/*
* put the dependencies here
* if API_ENDPOINT and API_KEY are defined outside the component no need to put them as dependency
*/
props.latitude,
props.longitude,
]);
But If I remember correctly linter may complain about dependency like props.latitude
and suggest to assign it to some variable before the useCallback
, and then use that as a dependency like:
let latitude = props.latitude; // then use latitude as dependency