如何解决代码中的无限循环?

How can I solve infinite loop in my code?

提问人:Fatih Demirbaş 提问时间:11/17/2023 更新时间:11/17/2023 访问量:71

问:

我的代码中有无限循环的问题。我正在尝试将图标设置为我的天气预报列表。但是我得到了“太多的重新渲染。React 限制了渲染的数量,以防止无限循环。错误。

有重要信息:我不能将此方法与useEffect一起使用。它会导致有关我的加载屏幕的任何错误。

我导入了这些图标:

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'

有我的selectIcon函数。我正在使用 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;
    }
  }

我正在尝试在 JSX 上实现这一点。我认为这里是问题的原因。但是我无法解决这个问题。这是我的组件:

return (
    <div className="WeeklyForecast">
      <div className="Prev-Btn">
        <button onClick={prevClick}>&lt;</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}>&gt;</button>
      </div>
    </div>
  );

我正在尝试将图标设置为我的天气预报列表。但是我得到了“太多的重新渲染。React 限制了渲染的数量,以防止无限循环。错误。

javascript 反应js jsx

评论

1赞 pytness 11/17/2023
您能否更新您的代码示例以包含以下定义?setWeatherIcon

答:

1赞 Ale_Bianco 11/17/2023 #1

您可以修改函数以返回所选图标,而不是直接更新函数内部的状态。然后,您可以在 JSX 中调用此函数,而不会导致重新渲染。selectIcon

const selectIcon = (type) => {
  switch (type) {
    case "sunny":
      return SunnyIcon;
    case "rainy":
      return RainyIcon;
    case "sunny rainy":
      return SunnyRainIcon;
    case "thunder":
      return ThunderIcon;
    case "sunny cloudy":
      return SunnyCloud;
    default:
      return null; // or a default icon
  }
}

return (
  <div className="WeeklyForecast">
    <div className="Prev-Btn">
      <button onClick={prevClick}>&lt;</button>
    </div>
    <div className="Forecast-List">
      {days.map((day) => (
        <div key={day}>
          <p>{day}</p>
          {selectIcon(selectedWeekData[day].type) && (
            <img src={selectIcon(selectedWeekData[day].type)} alt="" />
          )}
          <p>{selectedWeekData[day].degree}°</p>
        </div>
      ))}
    </div>
    <div className="Next-Btn">
      <button onClick={nextClick}>&gt;</button>
    </div>
  </div>
);
0赞 Nima Ka 11/17/2023 #2

我建议的第一件事是开关大小写(重复setWeatherIcon)函数可能是问题的原因。

我的建议:请将其提取到组件之外,看看问题是否仍然存在。

评论

0赞 David 11/17/2023
在每次渲染时更新状态确实是导致问题的原因。但是,简单地将该代码按原样移动到组件外部并不能解决问题。它只会用一个问题代替另一个问题。( 不存在于组件之外,也无法存在。setWeatherIcon
0赞 David 11/17/2023 #3

在每次渲染时,您都这样做:

selectIcon(selectedWeekData[day].type)

它调用更新状态的函数:

setWeatherIcon(SunnyIcon);

状态更新会触发重新渲染,重新调用上述代码,触发重新渲染,重新调用上述代码,等等(您还为数组中的每个元素更新了一个状态值,这没有多大意义,因为无论如何只有最后一次更新才会生效。

不要在每次渲染时更新状态。

为什么你甚至需要为此使用状态?看起来您只想根据值选择一个图标。因此,只需返回该图标:

const selectIcon = (type) => {
  switch (type) {
    case "sunny":
      return SunnyIcon;
    case "rainy":
      return RainyIcon;
    case "sunny rainy":
      return SunnyRainIcon;
    case "thunder":
      return ThunderIcon;
    case "sunny cloudy":
      return SunnyCloud;
  }
}

并内联调用该函数:

<div key={day}>
  <p>{day}</p>
  <img src={selectIcon(selectedWeekData[day].type)} alt="" />
  <p>{selectedWeekData[day].degree}°</p>
</div>