I have a problem with infinite loop in my code. I am trying set icons to my weather forecast list. But I am getting "Too many re-renders. React limits the number of renders to prevent an infinite loop." error.
There is important information: I can’t using this method with useEffect. It cause any error about my loading screen.
I have imported these icons:
import ThunderIcon from '../Images/ThunderIcon.svg'
import SunnyIcon from '../Images/SunnyIcon.svg'
import SunnyCloud from '../Images/SunnyCloud.svg'
import SunnyRainIcon from '../Images/SunnyRainIcon.png'
import RainyIcon from '../Images/RainyIcon.svg'
There is my selectIcon function. I am setting icons with switch-case:
const selectIcon = (type) => {
switch (type) {
case "sunny":
setWeatherIcon(SunnyIcon);
break;
case "rainy":
setWeatherIcon(RainyIcon);
break;
case "sunny rainy":
setWeatherIcon(SunnyRainIcon);
break;
case "thunder":
setWeatherIcon(ThunderIcon);
break;
case "sunny cloudy":
setWeatherIcon(SunnyCloud);
break;
}
}
And I am trying implement this on JSX. I think reason of problem in here. But I can’t solve this problem. Here is my component:
return (
<div className="WeeklyForecast">
<div className="Prev-Btn">
<button onClick={prevClick}><</button>
</div>
<div className="Forecast-List">
{days.map((day) => (
<div key={day}>
<p>{day}</p>
{selectIcon(selectedWeekData[day].type)}
<img src={weatherIcon} alt="" />
<p>{selectedWeekData[day].degree}°</p>
</div>
))}
</div>
<div className="Next-Btn">
<button onClick={nextClick}>></button>
</div>
</div>
);
I am trying set icons to my weather forecast list. But I am getting "Too many re-renders. React limits the number of renders to prevent an infinite loop." error.
3
Answers
You can modify your
selectIcon
function to return the selected icon rather than directly updating the state inside the function. Then, you can call this function inside the JSX without causing a re-render.The first thing that I’d suggest is that the switch-case (repetition of setWeatherIcon) function might be the cause of the problem.
My suggestion: Please extract it outside of component and see if the issue still remains.
On every render you do this:
Which calls a function that updates state:
State updates trigger a re-render, which re-invokes the above code, which triggers a re-render, which re-invokes the above code, etc., etc. (You’re also updating that one state value for every element in an array, which doesn’t make much sense as only the last update would take effect anyway.)
Don’t update state on every render.
Why do you even need to use state for this anyway? It looks like you just want to select an icon based on a value. So just return that icon:
And call that function inline: