Fetch / TemplateLiteral проблема передачи данных в React - PullRequest
0 голосов
/ 11 марта 2020

Я создаю приложение Weather, которое извлекает данные о местоположении и дате из браузера. Получив данные о местоположении, приложение отображает заголовок, который сообщает вам сезон на основе широты и месяца, предоставляет окно GoogleMap для вашего выбранного местоположения и извлекает данные из http://api.weatherapi.com/v1, чтобы получить 5 прогноз Я специально использую проп-бурение для этого проекта, чтобы показать понимание однонаправленного потока данных, поэтому я стараюсь избегать использования хуков для этого конкретного приложения. У меня также установлен условный рендеринг для предупреждений.

Все работает !!! Мой широта / долгота корректно сохраняется и сохраняется в моем объекте состояния, как и мой первоначальный запрос на выборку "Chica go" из API погоды для данных WeatherForecast. У меня есть два компонента внутри приложения: SeasonDisplay для отображения заголовка сезона и компонент LocationData, который передает необходимые координаты широты и долготы вниз в качестве реквизита. *** SeasonDisplay работает должным образом.

import React from "react";
import SeasonDisplay from './SeasonDisplay';
import './SeasonDisplay.css';
import Loader from './loader.js';
import LocationData from "./LocationData";
import "./App.css";
class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            lat: null,
            lon: null,
            mapData: [],
            weatherForecast: [],
            errorMessage: null
        }
    }
    async componentDidMount() {
        await window.navigator.geolocation.getCurrentPosition(
            (position) => {
                this.setState({ lat: position.coords.latitude });
                this.setState({ lon: position.coords.longitude });
            },
            (error) => this.setState({ errorMessage: error.message })
        );
        const response = await fetch(`http://api.weatherapi.com/v1/forecast.json?key=///apiKey///&q="Chicago"&days=5`)
        const data = await response.json();
        console.log(data);
        this.setState({ weatherForecast: data.forecast.forecastday });
    }
    renderContent() {
        if(this.state.errorMessage || !this.state.lat) {
            return <h2>Error: {this.state.errorMessage}</h2>;
        } else if (!this.state.errorMessage && this.state.lat) {
            return (
                    <div id="container">
                        <div>
                            <SeasonDisplay
                                lat={this.state.lat}
                                lon={this.state.lon}
                            />
                        </div>
                        <div id="locationData">
                            <LocationData
                                lat={this.state.lat}
                                lon={this.state.lon}
                                weatherForecast={this.state.weatherForecast}
                            />
                        </div>
                    </div>
            );
        }
        return (
            <div>
                <Loader message="Waiting on You..." />
            </div>
        )
    };
    render() {
        return (
            <div id="container">
                {this.renderContent()}
            </div>
        )
    }
}
export default App;

В моем компоненте LocationData я беру реквизиты lat / lon и передаю их двум другим компонентам, GoogleApiWrapper и WeatherCard.

*** GoogleApiWrapper работает, как и ожидалось, поэтому я знаю, что я правильно передаю свои реквизиты в компонент LocationData и что состояние из приложения передает данные вниз, в отличие от нуля или неопределенности.

import React from "react";
import GoogleApiWrapper from "../APIs/mapsAPI";
import WeatherCard from "./WeatherCard";
import "./LocationData.css";
const LocationData = props => {
  return (
    <div className="locationData">
      <GoogleApiWrapper
        lat={props.lat}
        lon={props.lon}
      />
      <WeatherCard
        lat={props.lat}
        lon={props.lon}
        weatherForecast={props.weatherForecast}
      />
    </div>
  );
};
export default LocationData;

Отсюда, широта и долгота пропускаются к компоненту WeatherCard, который отображает данные индекса weatherForecast на карту, которая отображается рядом с картой. (исправить это, прежде чем я изменить поток карт). В качестве теста, чтобы убедиться, что реквизит проходит, я добавил lat и lon к карте погоды, чтобы я мог видеть данные в ReactDevTools / Comonents, и данные Lat / Lon там.

Так что все работает.

**** Вот проблема ****

Я не могу заставить значения состояния широты / долготы правильно проходить в запросе на выборку. Я несколько раз пробовал использовать литералы шаблонов, но API do c сбивает с толку. Я использовал топор ios ранее, но удалил его, потому что, пытаясь передать ключевые / значения параметров, я продолжал получать такие города, как Нуль в Южной Америке или Лат в Норвегии .....

, в документации говорится передайте его как:

Latitude and Longitude (Decimal degree) e.g: q=48.8567,2.3508

Итак, я попытался передать различные версии

const response = await fetch(`http://api.weatherapi.com/v1/forecast.json?key=///apiKey///&q=${this.props.lat},${this.props.lon}&days=5`)

, чтобы указать местоположение c конечному пользователю, но он продолжает передавать возвращаемые результаты из Null в Эквадоре ... Таким образом, мое значение lat передается до того, как заданы данные о местоположении, хотя в ReactDevTools правильно отображаются и lat, и long.

Как передать значения lat / lon в получить данные моего прогноза для соответствующего местоположения ???

Кроме того, это мое первое сообщение, так что потерпите меня, пока я пытаюсь следить за форматированием, рискуя перераспределением ... Любая обратная связь будет премиальной.

1 Ответ

0 голосов
/ 11 марта 2020

Состояние установки в основном асинхронное c, поэтому, если вы хотите использовать вновь установленные значения состояния, вы должны рассмотреть это в обратном вызове setState. Также избегайте нескольких вызовов setState, вы можете объединить их в один:

  async componentDidMount() {
    await window.navigator.geolocation.getCurrentPosition(
      position => {
        const { latitude, longitude } = position.coords;
        this.setState(
          {
            lat: latitude,
            lon: longitude,
          },
          async () => {
            // use calback here
            const response = await fetch(
              `http://api.weatherapi.com/v1/forecast.json?key=///apiKey///${this.state.lat},${this.state.lon}&days=5`
            );
            const data = await response.json();
            console.log(data);
            this.setState({
              weatherForecast: data.forecast.forecastday,
            });
          }
        );
      },
      error =>
        this.setState({
          errorMessage: error.message,
        })
    );
  }
...