React - как установить состояние с данными из обработанного обещания - PullRequest
1 голос
/ 10 июля 2020

Я изо всех сил пытаюсь перевести свои данные из запроса на выборку в состояние моего контейнера

Мой запрос на выборку хранится в api. js и выглядит так - он извлекает ключ из константы что нормально: -

import { openWeatherKey } from './constants';

const getWeather = async() => {
    const base = "https://api.openweathermap.org/data/2.5/onecall";
    const query = `?lat=52.6&lon=-2.2&exclude=hourly,daily&appid=${openWeatherKey}`;

    const response = await fetch(base + query);
    const data = await response.json();

    return data;
}

export { getWeather };

Мой контейнер выглядит так: -

import React, { Component } from "react";
import './weather.css';
import { getWeather } from './api';

class Spy extends Component {

    constructor() {
        super()
        this.state = {test(){return "this is a test"}}
    }

    render() {
        return (
            <div id="spy-weather" className="app-border">
                <h3 className="spy-name">Weather at { this.props.location } {this.state.test()}</h3> 
            </div>
        )
    }
}

(() => {
    getWeather().then(data => {
        console.log(data);  
    })
})();  

export { Spy as Weather };

У меня есть IIFE, который делает запрос и выводит результаты на консоль. Вы можете видеть это между объявлением класса и оператором экспорта выше.

Вот результаты из консоли - запрос работает нормально

{lat: 52.6, lon: -2.2, timezone: "Europe/London", timezone_offset: 3600, current: {…}}
current: {dt: 1594401262, sunrise: 1594353486, sunset: 1594412995, temp: 289.05, feels_like: 286.49, …}
lat: 52.6
lon: -2.2
timezone: "Europe/London"
timezone_offset: 3600
__proto__: Object

Что мне не удается сделать, так это установить состояние с данными из разрешенного обещания. Я пробовал разные вещи, включая некоторые решения, которые я видел, которые не работали.

Как мне разместить и запустить функцию в контейнере, а затем обновить состояние с данными?

Я новичок в React, как вы, наверное, заметили.

С искренней благодарностью,

Фил

Ответы [ 2 ]

1 голос
/ 10 июля 2020

В компонентах на основе классов метод жизненного цикла, известный как componentDidMount , используется для выполнения каких-либо действий после монтирования компонента. В вашем случае переместите код в IIFE в методе componentDidMount.

Создайте свойство в объекте state, которое будет содержать данные о погоде. При желании вы также можете создать свойство в объекте state для хранения любого сообщения об ошибке, которое может возникнуть во время выборки данных из API.

this.state = {
   weatherData: null,
   error: ''
};

, а затем вызвать функцию getWeather() из componentDidMount() метод жизненного цикла

componentDidMount() {
    getWeather()
      .then(data => {
        this.setState({ weatherData: data });
      })
      .catch(error => this.setState({ error: error.message }));
}

В функциональных компонентах ловушка useEffect используется для выполнения любых побочных эффектов, таких как выборка данных из API. Состояние в функциональных компонентах сохраняется с помощью useState hook.

Если вы используете функциональный компонент, то ваш код будет выглядеть так:

const [weatherData, setWeatherData] = useState(null);
const [error, setError] = useState(null);

useEffect(() => {
    getWeather()
      .then(data => {
          setWeatherData(data);
      })
      .catch(error => setError(error.message));
}, []);
0 голосов
/ 10 июля 2020
this.state = {test(){return "this is a test"}}

Это недопустимая структура для управления состоянием, правильный путь

getWeather().then(data => {
        console.log(data);
        this.setState({ weatherData: data });
})

тоже структура состояний

state = {
  someProperty: value,
  someArray: [],
  weatherData: {}
}
...