React-приложение Прогноз погоды
Приложение, которое показывает прогноз погоды для определённых населённых пунктов.
1. Регистрируемся здесь https://openweathermap.org/forecast5
На почту приходит API key
2. Создаём приложение -weather
Для этого выполняем команду
create-react-app weather
3. Создаём компонент WeatherDisplay
Пока что он отображает произвольный текст
class WeatherDisplay extends Component {
render() {
return (
<h1>Displaying some Weather!</h1>
);
}
}
4. Изменяем компонент App, чтобы отобразить WeatherDisplay:
class App extends Component {
render() {
return (
<div className="App">
<WeatherDisplay name={"12345"} />
</div>
);
}
}
name={"12345"} это props - свойство компонента WeatherDisplay, которое из компонента App можно передать в WeatherDisplay
5. В начале файла App добавляем список городов, для которых будем отображать погоду
const PLACES = ["London", "Moscow", "Kiev", "Minsk"];
6. При помощи метода map создадим тег button для каждого города
return (
<div className="App">
<WeatherDisplay name={"12345"} />
{PLACES.map((place, index) => (
<button
key={index}
onClick={() => {
console.log('Clicked index '+index);
}}
>
{place.name}
</button>
))}
</div>
);
По клику по кнопке в консоль выводится индекс каждого города в списке.
7. Нам нужно хранить в App и передавать в WeatherDisplay название города, по которому кликнули. Для этого используем state
state = {
activePlace: 0,
};
Здесь 0 это позиция города в массиве, то есть город по умолчанию - London
8. Изменим код функции onClick, чтобы при клике по кнопке менялось значение state
{PLACES.map((place, index) => (
<button
key={index}
onClick={() => {
this.setState({ activePlace: index });
}}
>
{place}
</button>
))}
9. В компонент WeatherDisplay добавим название города
<WeatherDisplay
key={activePlace}
name={PLACES[activePlace]} />
10. Код компонента App
import React, {Component} from 'react';
import './App.css';
import WeatherDisplay from './components/WeatherDisplay/WeatherDisplay';
const PLACES = ["London", "Moscow", "Kiev", "Minsk"];
export default class App extends Component {
state = {
activePlace: 0,
};
render() {
const activePlace = this.state.activePlace;
return (
<div className="App">
{PLACES.map((place, index) => (
<button
key={index}
onClick={() => {
this.setState({ activePlace: index });
}} >
{place}
</button>
))}
<WeatherDisplay
key={activePlace}
name={PLACES[activePlace]} />
</div>
);
}
11. Переходим к компоненту WeatherDisplay
Установим для него state
state = {
weatherData: null
};
То есть пока мы ничего не знаем о погоде. Но хотим узнать. Как это сделать
12. Для получения данных о погоде используем полученный на первом шаге API key
12. Для получения данных о погоде используем полученный на первом шаге API key
Вот по такой ссылке https://api.openweathermap.org/data/2.5/weather?q=London&appid=b1b35bba8b434a28a0be2a3e1071ae5b нам откроются данные о погоде в Лондоне
Здесь
London - название города,
b1b35bba8b434a28a0be2a3e1071ae5b - API key
13. Пишем функцию
componentDidMount() {
const name = this.props.name;
const URL = "https://api.openweathermap.org/data/2.5/weather?q=" +
name +
"&appid=b1b35bba8b434a28a0be2a3e1071ae5b";
fetch(URL).then(res => res.json()).then(json => {
this.setState({ weatherData: json });
});
}
Краткое содержание кода функции
- Когда компонент WeatherDisplay будет создан - componentDidMount()
- Название города мы возьмём из props, который передали в App
- Затем используя это название сгенерируем ссылку
- И обработаем данную ссылку асинхронно, чтобы получить данные о погоде
this.setState({ weatherData: json });
});
Результатом выполнения данной функции будет помещение в state данных weatherData: json
14. Рассмотрим содержимое render компонента WeatherDisplay
- weatherData равно текущему состоянию state
const weatherData = this.state.weatherData;
- Изначально оно было определено нами как null. и если данные не пришли, пишем Loading - ждём данные
if (!weatherData) return <div>Loading</div>;
- генерируем ссылку на иконку, которую будем показывать возле названия города
const weather = weatherData.weather[0];
const iconUrl = "http://openweathermap.org/img/w/" + weather.icon + ".png";
15. Выводим данные о погоде
<div>
<h1>
{weather.main} in {weatherData.name}
<img src={iconUrl} alt={weatherData.description} />
</h1>
<p>Current: {(weatherData.main.temp - 273.15).toFixed(2)}°С</p>
<p>High: {(weatherData.main.temp_max - 273.15).toFixed(2)}°С</p>
<p>Low: {(weatherData.main.temp_min - 273.15).toFixed(2)}°С</p>
<p>Wind Speed: {weatherData.wind.speed} mi/hr</p>
</div>
Выражение (weatherData.main.temp - 273.15).toFixed(2) понадобилось чтобы перевести данные из градусов Кельвина в градусы Цельсия и округлить полученный результат до двух знаков после запятой
16. Код компонента WeatherDisplay
import React, {Component} from 'react';
export default class WeatherDisplay extends Component {
state = {
weatherData: null
};
componentDidMount() {
const name = this.props.name;
const URL = "https://api.openweathermap.org/data/2.5/weather?q=" +
name +
"&appid=b1b35bba8b434a28a0be2a3e1071ae5b";
fetch(URL).then(res => res.json()).then(json => {
this.setState({ weatherData: json });
});
}
render() {
const weatherData = this.state.weatherData;
if (!weatherData) return <div>Loading</div>;
const weather = weatherData.weather[0];
const iconUrl = "http://openweathermap.org/img/w/" + weather.icon + ".png";
return (
<div>
<h1>
{weather.main} in {weatherData.name}
<img src={iconUrl} alt={weatherData.description} />
</h1>
<p>Current: {(weatherData.main.temp - 273.15).toFixed(2)}°С</p>
<p>High: {(weatherData.main.temp_max - 273.15).toFixed(2)}°С</p>
<p>Low: {(weatherData.main.temp_min - 273.15).toFixed(2)}°С</p>
<p>Wind Speed: {weatherData.wind.speed} mi/hr</p>
</div>
);
}
}