React-приложение Прогноз погоды на 5 дней



Приложение, которое показывает прогноз погоды на 5 дней для определённого населённого пункта.

1. Регистрируемся здесь https://openweathermap.org/forecast5
На почту приходит API key

2. Создаём приложение my-weather-app
Для этого выполняем команду
create-react-app my-weather-app

3. Создаём компонент WeekContainer

import React from 'react';

class WeekContainer extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello World!</h1>
      </div>
    )
  }
}

export default WeekContainer;

4. Добавляем компонент WeekContainer в App

import React, { Component } from 'react';
import './App.css';
import WeekContainer from './WeekContainer';

class App extends Component {
  render() {
    return (
      <div className="App">
        <WeekContainer />
      </div>
    );
  }
}

export default App;

5. Для получения информации о прогнозе погоды за 5 дней используем ссылку вот такого плана:
Здесь
Kiev - название города, 
a9a3a62789de80865407c0452e9d1c27 - API key
&lang=ru - язык отображения описания погоды русский
&units=metric - температура в градусах Цельсия

6. Обрабатываем данную ссылку асинхронно

componentDidMount = () => {
    const weatherURL =
    "https://api.openweathermap.org/data/2.5/forecast?q=Kiev&lang=ru&units=metric&APPID=a9a3a62789de80865407c0452e9d1c27"
fetch(weatherURL)
    .then(res => res.json())
    .then(data => console.log("Data List Loaded", data.list))
  }

7. Пока что всё, что делает данная функция - выводит данные о погоде за каждые три часа в консоль. Таким образом в сутки получается 24 / 3 = 8 массивов с данными, за 5 суток - максимум, который возвращает сервер для бесплатных API - 40 массивов.

Чтобы получать данные только в определённое время суток, воспользуемся фильтром:

  componentDidMount = () => {
    fetch(weatherURL)
    .then(res => res.json())
    .then(data => {
      const dailyData = data.list.filter(reading => reading.dt_txt.includes("18:00:00"))
    })
  }

Теперь мы получаем данные о погоде раз в сутки в 18:00

8. Создаём  карточки с погодой для каждого дня

Для этого создадим компонент Card и будем рендерить его при помощи метода map массива dailyData

Код компонента WeekContainer полностью:

import React from 'react';
import Card from '../Card/Card';

const weatherURL = "https://api.openweathermap.org/data/2.5/forecast?q=Kiev&lang=ru&units=metric&APPID=a9a3a62789de80865407c0452e9d1c27";

class WeekContainer extends React.Component {
  state = {
    days: []
  }

  componentDidMount = () => {
    fetch(weatherURL)
    .then(res => res.json())
    .then(data => {
      const dailyData = data.list.filter(reading => reading.dt_txt.includes("18:00:00"))
      this.setState({days: dailyData})
    })
  }

  formatCards = () => {
    return this.state.days.map((day, index) => <Card day={day} key={index}/>)
  }

  render() {
    return (
      <div className="container">
      <h1 className="display-1 jumbotron">5-Day Forecast.</h1>
      <h5 className="display-5 text-muted">New York, US</h5>
        <div className="row justify-content-center">

          {this.formatCards()}

        </div>
      </div>
    )
  }
}

export default WeekContainer

9. Добавление дня недели на карту

Мы хотим, чтобы каждая карта отображала день недели

Номер текущего дня недели возвращает функция
new Date().getDay()

Название дня недели выведет функция
new Date().toLocaleString('ru', {weekday: 'long'})

В массиве dailyData текущая дата в секундах хранится в свойстве dt
Переводим её в миллисекунды и сохраняем название дня недели в переменную weekdayName:

const ms = this.props.day.dt * 1000;
const weekdayName = new Date(ms).toLocaleString('ru', {weekday: 'long'});

10. Добавление иконки с погодой на карту

Иконки с погодой берём здесь: https://websygen.github.io/owfont/
Скачиваем, разархивируем, помещаем папку с иконками в папку public

OpenWeatherMap API содержит идентификаторы иконок owfont. Чтобы иконка с погодой отобразилась, используем код

const imgURL = "owf owf-"+ this.props.day.weather[0].id +" owf-5x icon-style"
<i className={imgURL}></i>

11. Полностью код компонента Card

import React from 'react';
import './Card.css';

class Card extends React.Component {

  render() {    
    const ms = this.props.day.dt * 1000;
    const weekdayName = new Date(ms).toLocaleString('ru', {weekday: 'long'});

    const imgURL = "owf owf-"+ this.props.day.weather[0].id +" owf-5x icon-style"

    return (
      <div className="col-auto">
        <div className="card bg-light">
          <h3 className="card-title">{weekdayName}</h3>
          <i className={imgURL}></i>
          <h2>{Math.round(this.props.day.main.temp)} °C</h2>
          <div className="card-body">
            <p className="card-text">{this.props.day.weather[0].description}</p>
          </div>
        </div>
      </div>
    )
  }
}

export default Card