Пишем информер погоды на 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
Пример того, что получилось на картинке в начале статьи.
-
- Михаил Русаков
Комментарии (0):
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.