Uncaught错误:React限制渲染次数以防止无限循环(ReactAnimatedWeather)



我使用天气API制作了天气应用程序,当我在里面有图标代码(switchcase循环)时,我得到了无限循环错误。我希望icon由API的当前天气状态更新!有人能帮我一下吗?如何解决无限循环错误…?

import React, { useState, useEffect } from 'react';
import ReactAnimatedWeather from 'react-animated-weather';
function Weather() {
const [weather, setWeather] = useState({
city: undefined,
temp_current: undefined,
temp_max: undefined,
temp_min: undefined,
current: undefined,
icon: undefined,
});
const convertCelsius = (temp) => {
let cel = Math.floor(temp - 273.15);
return cel;
};
const defaults = {
color: 'white',
size: 100,
animate: true,
};
const getWeather = async (lat, lon) => {
const API_KEY = '9916e4e6fd6079aa9a9fec8e0c218fc5';
const API_URL = `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${API_KEY}&lang=kr`;
const response = await fetch(API_URL);
const data = await response.json();
console.log(data);
setWeather({
city: data.name,
temp_current: convertCelsius(data.main.temp),
temp_max: convertCelsius(data.main.temp_max),
temp_min: convertCelsius(data.main.temp_min),
current: data.weather[0].main,
});
};
// icon
switch (weather.current) {
case 'Haze':
setWeather({ ...weather, icon: 'CLEAR_DAY' });
break;
case 'Clouds':
setWeather({ ...weather, icon: 'CLOUDY' });
break;
case 'Snow':
setWeather({ ...weather, icon: 'SNOW' });
break;
case 'Drizzle':
setWeather({ ...weather, icon: 'SLEET' });
break;
case 'Dust':
case 'Tornado':
setWeather({ ...weather, icon: 'WIND' });
break;
case 'Fog':
case 'Smoke':
setWeather({ ...weather, icon: 'FOG' });
break;
case 'Rain':
case 'Mist':
setWeather({ ...weather, icon: 'RAIN' });
break;
default:
setWeather({ ...weather, icon: 'CLEAR_DAY' });
break;
}
useEffect(() => {
// get geolocation
let lat, lon;
if ('geolocation' in navigator) {
console.log('geolocation available');
navigator.geolocation.getCurrentPosition(async (position) => {
try {
lat = position.coords.latitude;
lon = position.coords.longitude;
getWeather(lat, lon);
} catch (error) {
getWeather(37.53, 127.02);
console.log(error);
}
});
} else {
alert('geoloaction not available');
}
}, []);
return (
<div className="weather">
<div className="weather-info">
<h1 className="location">{weather.city}</h1>
<div className="temperature">
<p className="current">{weather.temp_current}&deg;</p>
<ul className="minmax">
<li>{weather.temp_min}&deg;</li>
<li>{weather.temp_max}&deg;</li>
</ul>
</div>
</div>
<div className="weather-icon">
<ReactAnimatedWeather
icon={weather.icon ? weather.icon : 'CLEAR_DAY'}
color={defaults.color}
size={defaults.size}
animate={defaults.animate}
/>
<p className="state">{weather.current}</p>
</div>
</div>
);
}
export default Weather;

你的开关块正在调用setState,它会重新渲染组件并再次调用开关块:

switch (weather.current) {
case 'Haze':
setWeather({ ...weather, icon: 'CLEAR_DAY' });
break;

将此开关块移动到useEffect函数中,以便在加载时运行一次,或者更好的是将图标加载为异步API调用函数的一部分,以检查每次对API的调用:

const getWeather = async (lat, lon) => {
const API_KEY = '9916e4e6fd6079aa9a9fec8e0c218fc5';
const API_URL = `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${API_KEY}&lang=kr`;
const response = await fetch(API_URL);
const data = await response.json();
console.log(data);

//Set Icon here
const weatherIcon = 
setWeather({
city: data.name,
temp_current: convertCelsius(data.main.temp),
temp_max: convertCelsius(data.main.temp_max),
temp_min: convertCelsius(data.main.temp_min),
current: data.weather[0].main,
icon: weatherIcon 
});
};

@Oliver BN说了什么或者试试这个

setWeather({
city: data.name,
temp_current: convertCelsius(data.main.temp),
temp_max: convertCelsius(data.main.temp_max),
temp_min: convertCelsius(data.main.temp_min),
current: data.weather[0].main,
icon: buildIcon(data.weather[0].main),
});
};
function buildIcon(current) {
switch (current) {
case "Haze":
return "CLEAR_DAY";
break;
case "Clouds":
return "CLOUDY";
break;
// ...
default:
return "CLEAR_DAY";
break;
}
}

最新更新