简体   繁体   English

反应:错误:重新渲染太多。 React 限制渲染次数以防止无限循环

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

this is my first time on stackoverflow, nice to meet y'all.这是我第一次上stackoverflow,很高兴认识你们。 I am pretty new to react.我很新的反应。 I am trying to learn hooks with a weather app I just built and I get this too many re-renders error.我正在尝试使用我刚刚构建的天气应用程序来学习钩子,但我收到了太多的重新渲染错误。 The app worked just fine with class components.该应用程序与 class 组件配合得很好。 I tried wrappign the handleInputChange in an arrow function but then the app didn't even call the api我尝试在箭头 function 中包装 handleInputChange 但随后应用程序甚至没有调用 api

This is the code:这是代码:

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;

Hi and welcome to stackoverflow community!您好,欢迎来到 stackoverflow 社区!

In that case you need to use an effect.在这种情况下,您需要使用效果。 Your component loop again and again because of your switch statement.由于您的 switch 语句,您的组件一次又一次地循环。

setBackground is called on every render if info.weather exist.如果info.weather存在,则在每次渲染时调用setBackground But calling setBackground trigger an new render also.但是调用setBackground也会触发一个新的渲染。 What you need is an effect depending on the value of info您需要的是取决于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>
  );
};

More informations about Effect: https://reactjs.org/docs/hooks-effect.html有关效果的更多信息: https://reactjs.org/docs/hooks-effect.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 React - 错误:重新渲染太多。 React 限制渲染次数以防止无限循环 - React - Error: Too many re-renders. React limits the number of renders to prevent an infinite loop React-Error:重新渲染太多。 React 限制渲染次数以防止无限循环 - React-Error: Too many re-renders. React limits the number of renders to prevent an infinite loop 错误:重新渲染过多。 React 限制了渲染的数量以防止无限循环。 - 反应 JS - Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. - React JS 错误:重新渲染过多。 React 限制渲染次数以防止无限循环。 反应 - Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. React 错误:重新渲染过多。 React 限制了渲染的数量以防止无限循环。 - 反应 - Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. - React 反应错误:重新渲染太多。 React 限制渲染次数以防止无限循环 - React Error: Too many re-renders. React limits the number of renders to prevent an infinite loop 未捕获的错误:重新渲染太多。 React 限制渲染次数以防止无限循环。 错误 - Uncaught Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. error 服务器错误错误:重新渲染太多。 React 限制渲染次数以防止无限循环 - Server Error Error: Too many re-renders. React limits the number of renders to prevent an infinite loop “未捕获的错误:重新渲染过多。React 限制渲染次数以防止无限循环。” - "Uncaught Error: Too many re-renders. React limits the number of renders to prevent an infinite loop." 错误:重新渲染过多。 React 限制渲染次数以防止无限循环 - Error: Too many re-renders. React limits the number of renders to prevent an infinite loop
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM