簡體   English   中英

反應:錯誤:重新渲染太多。 React 限制渲染次數以防止無限循環

[英]React: Error: Too many re-renders. React limits the number of renders to prevent an infinite loop

這是我第一次上stackoverflow,很高興認識你們。 我很新的反應。 我正在嘗試使用我剛剛構建的天氣應用程序來學習鈎子,但我收到了太多的重新渲染錯誤。 該應用程序與 class 組件配合得很好。 我嘗試在箭頭 function 中包裝 handleInputChange 但隨后應用程序甚至沒有調用 api

這是代碼:

import React, { useState } from "react";
import axios from "axios";
import "./App.css";

const dateBuilder = (today) => {
  let months = [
    "January",
    "February",
    "March",
    "April",
    "May",
    "June",
    "July",
    "August",
    "September",
    "October",
    "November",
    "December",
  ];
  let days = [
    "Sunday",
    "Monday",
    "Tuesday",
    "Wednesday",
    "Thursday",
    "Friday",
    "Saturday",
  ];
  let day = days[today.getDay()];
  let date = today.getDate();
  let month = months[today.getMonth()];

  return `${day} ${date} ${month}`;
};

const key = process.env.REACT_APP_WEATHER_API_KEY;

const App = () => {

  const [info, setInfo] = useState([]);

  const [background, setBackground] = useState("app");

  const handleInputChange = (event) => {
    console.log('event', event)
    if (event.key === "Enter") {
      const city = event.target.value;
      const apiUrl = `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${key}`;

      axios
        .get(apiUrl)
        .then((res) => {
          const { data } = res;
          console.log("api response", res);

            setInfo(data);
          console.log("info", info);
        })

        .catch((err) => console.log("err", err));
    }
  };

  if (info.weather) {
    switch (info.weather[0].main) {
      case "Rain":
        setBackground("rain");
        break;
      case "Clouds":
        setBackground("clouds");
        break;
      case "Snow":
        setBackground("snow");
        break;
      case "Fog":
        setBackground("fog");
        break;
      case "Drizzle":
        setBackground("drizzle");
      case "Thunderstorm":
        setBackground("thunderstorm");
      case "Clear":
        setBackground("app");
        break;
    }
  }

  return (
    <div className={background}>
      <main>
        <div className="search-box">
          <input
            type="text"
            className="search-bar"
            placeholder="search..."
            onKeyPress={handleInputChange}
          />
        </div>
        <div className="location-box">
          <div className="location">{info.name}</div>
          <div className="date">{dateBuilder(new Date())}</div>
        </div>
        {typeof info.main != "undefined" ? (
          <div>
            <div className="weather-box">
              <div className="temp">
                {Math.round(info.main.temp - 273.15)}º C
              </div>

              <div className="weather">{info.weather[0].main}</div>
              <div className="pressure">{info.main.pressure} mbar</div>
              <div className="pressure">{info.main.humidity} % humidity</div>
            </div>
          </div>
        ) : (
          <></>
        )}
      </main>
    </div>
  );
};

export default App;

您好,歡迎來到 stackoverflow 社區!

在這種情況下,您需要使用效果。 由於您的 switch 語句,您的組件一次又一次地循環。

如果info.weather存在,則在每次渲染時調用setBackground 但是調用setBackground也會觸發一個新的渲染。 您需要的是取決於info值的效果

const App = () => {

  const [info, setInfo] = useState([]);

  const [background, setBackground] = useState("app");

  useEffect(() => {
    if (info.weather) {
      switch (info.weather[0].main) {
        case "Rain":
          setBackground("rain");
          break;
        case "Clouds":
          setBackground("clouds");
          break;
        case "Snow":
          setBackground("snow");
          break;
        case "Fog":
          setBackground("fog");
          break;
        case "Drizzle":
          setBackground("drizzle");
        case "Thunderstorm":
          setBackground("thunderstorm");
        case "Clear":
          setBackground("app");
          break;
      }
    }}, [info])

  const handleInputChange = (event) => {
    console.log('event', event)
    if (event.key === "Enter") {
      const city = event.target.value;
      const apiUrl = `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${key}`;

      axios
        .get(apiUrl)
        .then((res) => {
          const { data } = res;
          console.log("api response", res);

            setInfo(data);
          console.log("info", info);
        })

        .catch((err) => console.log("err", err));
    }
  };

  return (
    <div className={background}>
      <main>
        <div className="search-box">
          <input
            type="text"
            className="search-bar"
            placeholder="search..."
            onKeyPress={handleInputChange}
          />
        </div>
        <div className="location-box">
          <div className="location">{info.name}</div>
          <div className="date">{dateBuilder(new Date())}</div>
        </div>
        {typeof info.main != "undefined" ? (
          <div>
            <div className="weather-box">
              <div className="temp">
                {Math.round(info.main.temp - 273.15)}º C
              </div>

              <div className="weather">{info.weather[0].main}</div>
              <div className="pressure">{info.main.pressure} mbar</div>
              <div className="pressure">{info.main.humidity} % humidity</div>
            </div>
          </div>
        ) : (
          <></>
        )}
      </main>
    </div>
  );
};

有關效果的更多信息: https://reactjs.org/docs/hooks-effect.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM