Простое приложение React Weather - работает в codeandbox, а не в VSCode? - PullRequest
1 голос
/ 25 февраля 2020

Я делаю новостное приложение React для погоды с Geolocation. Вот код Основной код находится в приложении. js. Ежедневно и Ежечасно только для отображения.

Приложение. js

import React, { useState, useEffect } from "react";
import Hourly from "./Components/Hourly";
import Daily from "./Components/Daily";

const App = () => {
    const [currentWeatherOne, setCurrentWeatherOne] = useState({});
    const [currentWeatherTwo, setCurrentWeatherTwo] = useState({});
    const [currentWeatherThree, setCurrentWeatherThree] = useState({});
    const [currentWeatherFour, setCurrentWeatherFour] = useState({});
    const [currentWeatherFive, setCurrentWeatherFive] = useState({});
    const [lat, setLat] = useState();
    const [long, setLong] = useState();
    const [today, setToday] = useState();
    const [tomorrow1, setTomorrow1] = useState({});
    const [tomorrow2, setTomorrow2] = useState({});
    const [refreshText, setRefreshText] = useState();

    const getPosition = () => {
        return new Promise((resolve, reject) => {
            navigator.geolocation.getCurrentPosition(resolve);
        });
    };

    const getWeather = async (lat, long) => {
        let a = await fetch(
            `https://api.openweathermap.org/data/2.5/forecast?lat=${lat}&lon=${long}&appid=dcadf332823cddfb979926a1414274e8&units=metric`
        );
        let b = await a.json();
        console.log(b);
        setCurrentWeatherOne(b.list[1]);
        setCurrentWeatherTwo(b.list[2]);
        setCurrentWeatherThree(b.list[3]);
        setCurrentWeatherFour(b.list[4]);
        setCurrentWeatherFive(b.list[5]);
        setToday(b.list[0]);
        setTomorrow1(b.list[11]);
        setTomorrow2(b.list[19]);
    };

    useEffect(() => {
        getPosition().then(data => {
            setLat(data.coords.latitude);
            setLong(data.coords.longitude);
            getWeather(data.coords.latitude, data.coords.longitude);
        });
    }, []);

    // console.log(currentWeatherOne, currentWeatherThree, currentWeatherFive);

    const refresh = () => {
        getWeather(lat, long);
        let hours = String(new Date().getHours());
        let minutes = String(new Date().getMinutes());
        let seconds = String(new Date().getSeconds());
        setRefreshText(
            `Updated as of: ${hours}:${minutes.length < 2 ? "0" : ""}${minutes}:${
            seconds.length < 2 ? "0" : ""
            }${seconds}`
        );
    };

    return (
        <div className="App">
            <header>Geolocation weather</header>
            <button onClick={refresh}>Refresh</button>
            <br />
            {refreshText}
            <hr />
            <h3>Hourly</h3>
            <div className="container-2">
                <Hourly
                    icon={currentWeatherOne.weather[0].icon}
                    time={currentWeatherOne.dt_txt}
                    minTemp={currentWeatherOne.main.temp_min}
                    maxTemp={currentWeatherOne.main.temp_max}
                    description={currentWeatherOne.weather[0].description}
                    humidity={currentWeatherOne.main.humidity}
                />
                <Hourly
                    icon={currentWeatherTwo.weather[0].icon}
                    time={currentWeatherTwo.dt_txt}
                    minTemp={currentWeatherTwo.main.temp_min}
                    maxTemp={currentWeatherTwo.main.temp_max}
                    description={currentWeatherTwo.weather[0].description}
                    humidity={currentWeatherTwo.main.humidity}
                />
                <Hourly
                    icon={currentWeatherThree.weather[0].icon}
                    time={currentWeatherThree.dt_txt}
                    minTemp={currentWeatherThree.main.temp_min}
                    maxTemp={currentWeatherThree.main.temp_max}
                    description={currentWeatherThree.weather[0].description}
                    humidity={currentWeatherThree.main.humidity}
                />
                <Hourly
                    icon={currentWeatherFour.weather[0].icon}
                    time={currentWeatherFour.dt_txt}
                    minTemp={currentWeatherFour.main.temp_min}
                    maxTemp={currentWeatherFour.main.temp_max}
                    description={currentWeatherFour.weather[0].description}
                    humidity={currentWeatherFour.main.humidity}
                />
                <Hourly
                    icon={currentWeatherFive.weather[0].icon}
                    time={currentWeatherFive.dt_txt}
                    minTemp={currentWeatherFive.main.temp_min}
                    maxTemp={currentWeatherFive.main.temp_max}
                    description={currentWeatherFive.weather[0].description}
                    humidity={currentWeatherFive.main.humidity}
                />
            </div>
            <h3>Daily</h3>
            <div className="container-1">
                <Daily
                    icon={today.weather[0].icon}
                    time={today.dt_txt}
                    minTemp={today.main.temp_min}
                    maxTemp={today.main.temp_max}
                    description={today.weather[0].description}
                    humidity={today.main.humidity}
                />
                <Daily
                    icon={tomorrow1.weather[0].icon}
                    time={tomorrow1.dt_txt}
                    minTemp={tomorrow1.main.temp_min}
                    maxTemp={tomorrow1.main.temp_max}
                    description={tomorrow1.weather[0].description}
                    humidity={tomorrow1.main.humidity}
                />
                <Daily
                    icon={tomorrow2.weather[0].icon}
                    time={tomorrow2.dt_txt}
                    minTemp={tomorrow2.main.temp_min}
                    maxTemp={tomorrow2.main.temp_max}
                    description={tomorrow2.weather[0].description}
                    humidity={tomorrow2.main.humidity}
                />
            </div>
        </div>
    );
};

export default App;

Ежедневно

import React from "react";

const Daily = ({ icon, time, minTemp, maxTemp, description, humidity }) => {
  let timeToShow = time.split(" ")[0];
  let one = timeToShow.split("-")[0];
  let two = timeToShow.split("-")[1];
  let three = timeToShow.split("-")[2];

  maxTemp = Math.floor(maxTemp);
  minTemp = Math.floor(minTemp);
  description = description
    .split(" ")
    .map(word => {
      return word[0].toUpperCase() + word.substring(1);
    })
    .join(" ");

  return (
    <div className="weather">
      <div>
        {three}-{two}-{one}
      </div>
      <img
        src={`https://openweathermap.org/img/w/${icon}.png`}
        alt="weather icon"
      />
      <div>
        <div>
          <span className="temp">{maxTemp}</span>
          <span>{minTemp}</span>
        </div>
        <br />
        <div>{description}</div>
        <br />
        {humidity}% humidity
      </div>
    </div>
  );
};

export default Daily;

Ежечасно

import React from "react";

const Hourly = ({ description, humidity, time, icon, minTemp, maxTemp }) => {
  let timeToShow = time.split(" ")[1];
  let first = timeToShow.split(":")[0];
  let second = timeToShow.split(":")[1];
  maxTemp = Math.floor(maxTemp);
  minTemp = Math.floor(minTemp);
  description = description
    .split(" ")
    .map(word => {
      return word[0].toUpperCase() + word.substring(1);
    })
    .join(" ");

  return (
    <div className="weather">
      <div>
        {first}:{second}
      </div>
      <img
        src={`https://openweathermap.org/img/w/${icon}.png`}
        alt="weather icon"
      />
      <div>
        <div>
          <span className="temp">{maxTemp}</span>
          <span>{minTemp}</span>
        </div>
        <br />
        <div>{description}</div>
        <br />
        {humidity}% humidity
      </div>
    </div>
  );
};

export default Hourly;

В кодах и окнах иногда это не работает, поэтому я должен прокомментировать все Ежедневно и Ежечасно компонентов, подождите 2 секунды, пока коды и коробка перезагрузятся, и раскомментируйте их, и обычно это будет работать.

Не так на VSCode. Он скажет, что currentWeatherOne.weather не определен , что означает, что currentWeatherOne пытается получить доступ к информации, которой еще нет. Я не понимаю, не в этом ли смысл использования обещания? Используете asyn c, ожидаете et c? Чтобы он ожидал возврата результата, затем отобразите его? Какова бы ни была причина, почему она работает с кодами, а не с VSCode?

Очень хотелось бы получить отзывы и помощь. Спасибо всем!

1 Ответ

0 голосов
/ 25 февраля 2020

currentWeatherOne изначально установлен на пустой объект {}, и вы пытаетесь получить доступ к currentWeatherOne.weather[0].icon в разделе возврата. поскольку weather пока недоступно в currentWeatherOne, вы получаете эту ошибку.

UseEffect вызывается после первого рендера, поэтому ваш getWeather для получения информации о погоде вызывается после первоначального рендеринга. До этого времени currentWeatherOne был просто пустым объектом.

Устранена проблема здесь - https://codesandbox.io/s/tender-wood-b4kuh

Надеюсь, это поможет.

...