Пишем информер погоды на React
			Доброго времени суток всем! В этой статье я покажу Вам как просто можно создать приложение на React. Данное React приложение будет показывать погоду для любого города или страны мира. Итак...
Структура папок внутри src следующая:
src:.
│   App.js
│   index.css
│   index.html
│   index.js
│
└───assets           # фоны
        cold-bg.jpg  # для холодной погоды
        warm-bg.jpg  # для теплой погоды
    
    Файлы:
package.json
{
  "name": "weather-react",
  "version": "0.1.0",
  "scripts": {
    "dev":  "rm -rf ./.cache && rm -rf ./dist && npx parcel src/index.html",
    "prod": "rm -rf ./.cache && rm -rf ./dist && npx parcel build src/index.html"
  },
  "dependencies": {
    "react": "^16.13.1",
    "react-dom": "^16.13.1"
  },
  "devDependencies": {
    "parcel-bundler": "^1.12.4"
  }
}
    
    index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Информер погоды на React</title>
</head>
<body>
    <div id="root"></div>
    <script src="./index.js"></script>
</body>
</html>
    
    index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));
    
    index.css
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
body {
  font-family: 'montseratt', sans-serif;
}
.app {
  background-image: url('./assets/cold-bg.jpg');
  background-size: cover;
  background-position: bottom;
  transition: 0.4 ease;
}
.app.warm {
  background-image: url('./assets/warm-bg.jpg');
}
main {
  min-height: 100vh;
  background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.75));
  padding: 25px;
}
.search-box {
  width: 100%;
  margin: 0 0 75px;
}
.search-box .search-bar {
  display: block;
  width: 100%;
  padding: 15px;
  appearance: none;
  background: none;
  border: none;
  outline: none;
  background-color: rgba(255, 255, 255, 0.5);
  border-radius: 0px 0px 16px 16px;
  margin-top: -25px;
  box-shadow: 0px 5px rgba(0, 0, 0, 0.2);
  
  color: #313131;
  font-size: 20px;
  transition: 0.4s ease;
}
.search-box .search-bar:focus {
  background-color: rgba(255, 255, 255, 0.75);
}
.location-box .location {
  color: #FFF;
  font-size: 32px;
  font-weight: 500;
  text-align: center;
  text-shadow: 3px 3px rgba(50, 50, 70, 0.5);
}
.location-box .date {
  color: #FFF;
  font-size: 20px;
  font-weight: 300;
  font-style: italic;
  text-align: center;
  text-shadow: 2px 2px rgba(50, 50, 70, 0.5);
}
.weather-box {
  text-align: center;
}
.weather-box .temp {
  position: relative;
  display: inline-block;
  margin: 30px auto;
  background-color: rgba(255, 255, 255, 0.2);
  border-radius: 16px;
  padding: 15px 25px;
  color: #FFF;
  font-size: 102px;
  font-weight: 900;
  text-shadow: 3px 6px rgba(50, 50, 70, 0.5);
  text-align: center;
  box-shadow: 3px 6px rgba(0, 0, 0, 0.2);
}
.weather-box .weather {
  color: #FFF;
  font-size: 48px;
  font-weight: 700;
  text-shadow: 3px 3px rgba(50, 50, 70, 0.5);
}
    
    App.js
import React, { useState } from 'react';
// доступ к API сервиса погоды
const api = {
  key: 'c7616da4b68205c2f3ae73df2c31d177',
  base: 'http://api.openweathermap.org/data/2.5/'
}
function App() {
  // действия при изменении города в поле ввода
  const [city, setCity] = useState('');
  // действия с данными погоды
  const [weather, setWeather] = useState({});
  // обработчик, который срабатывает когда нажата клавиша Enter
  const search = evt => {
    if (evt.key === 'Enter') {
      fetch(`${api.base}weather?q=${city}&units=metric&appid=${api.key}`) // отправляем запрос
        .then(res => res.json())  // ответ преобразуем в json
        .then(result => {         // работаем с результатом
          setWeather(result);
          setCity('');
          console.log(result);
        });
    }
  }
  // форматирование даты
  const format_date = (d) => {
    let months = ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'];
    let days = ['Воскресенье', 'Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота'];
    let day = days[d.getDay()];
    let date = d.getDate();
    let month = months[d.getMonth()];
    let year = d.getFullYear();
    return `${day} ${date} ${month} ${year}`
  }
  // JSX разметка
  return (
    <div className={(typeof weather.main != 'undefined') ? ((weather.main.temp > 16) ? 'app warm' : 'app') : 'app'}>
      <main>
        <div className='search-box'>
          <input 
            type='text'
            className='search-bar'
            placeholder='Поиск...'
            onChange={e => setCity(e.target.value)}
            value={city}
            onKeyPress={search}
          />
        </div>
        {(typeof weather.main != 'undefined') ? (
        <div>
          <div className='location-box'>
            <div className='location'>{weather.name}, {weather.sys.country}</div>
            <div className='date'>{format_date(new Date())}</div>
          </div>
          <div className='weather-box'>
            <div className='temp'>
              {Math.round(weather.main.temp)}°c
            </div>
            <div className='weather'>{weather.weather[0].main}</div>
          </div>
        </div>
        ) : ('')}
      </main>
    </div>
  );
}
export default App;
    
    Собирается и запускается это все вот так:
# установка пакетов
npm install
# запуск в dev
npm run dev
# сборка для prod
npm run prod
Пример того, что получилось на картинке в начале статьи.
- 
					Создано 28.05.2020 13:52:55
					 - 
					
					Михаил Русаков				 
			
		
			
				
				
Комментарии (0):
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.