首页 > 解决方案 > 如何修复在反应中显示天气图标的错误

问题描述

我正在使用 API 创建一个简单的天气应用程序,但我使用的是来自https://github.com/erikflowers/weather-icons的图标,我已经编写了根据我的值显示每个图标的功能从我的每个国家/地区的数据中获取,但我知道我错过了一些不允许我访问我所在州的图标价值的东西。

我的应用组件

import axios from 'axios';
import React, {useState} from 'react'
import InitialData from '../InitialData';
import "weather-icons/css/weather-icons.css";


const WeatherListing = () => {
    //States
    const [countryName,setCountryName] = useState(InitialData.name);
    const [temp, setTemp] = useState(InitialData.temp);
    const [maxTemp, setMaxTemp] = useState(InitialData.temp_max);
    const [minTemp, setMinTemp] = useState(InitialData.temp_min);
    const [WeatherDesc, setWeatherDesc] = useState(InitialData.description);
    const [name, setName] = useState("");
    const [weatherIcons, setWeatherIcons] = useState({
        Thunderstorm: "wi-thunderstorm",
        Drizzle: "wi-sleet",
        Rain: "wi-storm-showers",
        Snow: "wi-snow", 
        Atmosphere: "wi-fog",
        Clear: "wi-day-sunny",
        Clouds: "wi-day-fog"
    })
    
    

    //Display the icons based on the value
    const displayIcons = (icons, rangeId) => {
        switch(true) {
            case rangeId >=200 && rangeId < 232 :
                setWeatherIcons(icons.Thunderstorm);
                break;
            case rangeId >= 300 && rangeId <= 321: 
                setWeatherIcons(icons.Drizzle);
                break;
            case rangeId >= 500 && rangeId <= 521:
                setWeatherIcons(icons.Rain);
                break;
            case rangeId >= 600 && rangeId <= 622:
                setWeatherIcons(icons.Snow);
                break;
            case rangeId >= 701 && rangeId <= 781:
                setWeatherIcons(icons.Atmosphere);
                break;
            case rangeId === 800:
                setWeatherIcons(icons.Clear);
                break;
            case rangeId >= 801 && rangeId <= 804:
                setWeatherIcons(icons.Clouds);
                break;
            default : 
                setWeatherIcons(icons.Clouds)
        }
    }
    

    //submit function to get the data by country
    const submitCountry = (e) => {
        e.preventDefault();
        if(name) {
            try {
                const fetchData = async () => {
                const response = await axios.get(`https://api.openweathermap.org/data/2.5/weather?q=${name}&appid=${Api_Key}`)
                const result = await response.data;
                      setCountryName(result.name);
                      setTemp(convertToCeil(result.main.temp))
                      setMaxTemp(convertToCeil(result.main.temp_max))
                      setMinTemp(convertToCeil(result.main.temp_min))
                      setWeatherDesc(result.weather[0].description)  
                      console.log(result.weather[0].id)

                      displayIcons(setWeatherIcons, result.weather[0].id)
              }
              fetchData();
              
            } catch(error) {
                console.log(`Error : ${error}`)
            }

        }
        setName("")
        
    }

    //To convert number to ceil
    const convertToCeil = (temp) =>  {
        let cell = Math.floor(temp - 273.15);
        return cell
    }

    return (
        <section className="container">
            <form className="form-control" >
                <input type="text" 
                       placeholder="Search by country"
                       value={name}
                       onChange={(e)=> setName(e.target.value)}
                       />
                <button type="submit" onClick={submitCountry}>Search</button>
            </form>

            <article>
                <h1>{countryName}</h1>
                <h3>{temp}°C</h3>
                <i className={`wi ${weatherIcons}`}></i>
                <h2>{WeatherDesc}</h2>
                <h4>{maxTemp}°C<span>/</span>{minTemp}°C</h4>
            </article>
        </section>
        
    )
}

export default WeatherListing

你怎么看?

标签: reactjs

解决方案


我将首先只有一个状态来获取数据,而不是为您尝试获取的每个单独属性设置多个状态。通过一个状态,您可以访问返回的 Object 中的所有属性,并在 JSX 中使用它。

这应该可以根据与用户搜索的城市当前天气对应的 ID 为您提供天气图标。如果您对以下代码有更多疑问或遇到问题,请告诉我!

export default function App() {
          const [data, setData] = useState([]);
        
          const mainIcons = {
            Thunderstorm: "wi-thunderstorm",
            Drizzle: "wi-sleet",
            Rain: "wi-storm-showers",
            Snow: "wi-snow",
            Atmosphere: "wi-fog",
            Clear: "wi-day-sunny",
            Clouds: "wi-day-fog"
          };
          let apiKey = "key...";
        
          const submitCity = async (e) => {
            e.preventDefault();
        
            try {
              const res = await axios.get(
                `https://api.openweathermap.org/data/2.5/weather?q=${name}&appid=${apiKey}&units=metric`
              );
              setData(res.data);
            } catch (error) {
              console.log(error);
            }
          };
        
          
        
          
          const displayIconsById = (icon) => {
            switch (true) {
              case icon >= 200 && icon < 232:
                icon = weatherIcons.Thunderstorm;
                break;
              case icon >= 300 && icon <= 321:
                icon = weatherIcons.Rain;
                break;
        
              default:
                icon = "n/a";
            }
            return icon;
          };
        
          return (
            <div className="App">
              <h1>Get City</h1>
              <form action="submit">
                <input type="text" 
                   placeholder="Search by city"
                   value={name}
                   onChange={(e)=> setName(e.target.value)} />
                <button onClick={submitCountry} type="submit">
                  SUBMIT
                </button>
              </form>
        
              <h2>{data && data.name}</h2>
              <img src={displayIconsById(data.weather && data.weather[0].id)}/>
            </div>
          );
        }

推荐阅读