Для JavaScript существует большое количество сторонних библиотек, фреймворков и программных платформ, которые помогают разработчикам создавать разнообразные проекты на этом языке программирования. React — это один из инструментов, использующийся в фронтенд-разработке.
В этой инструкции мы расскажем, как создать простое приложение на React.
Установка React
Разрабатывать приложения на React можно в любой удобной для вас системе и среде разработки. Мы будем создавать приложение в IntelliJ IDEA в ОС Windows 10.
В первую очередь необходимо установить Node.js
Установка Node.js
Node.js — это среда выполнения кода JavaScript. Одно из системных требований React — установленный пакет Node.js.
Чтобы установить Node.js на Windows 10 выполните следующие действия:
- После установки откройте PowerShell от имени администратора.
- Получите список доступных версий командой nvm list available.
- Выберите версию и установите её командой nvm install <version><version> замените номером выбранной версии. Рекомендуется устанавливать LTS выпуски Node.js.
Установка React
Откройте терминал в вашей среде разработки или PowerShell от имени администратора и установите расширение CRA:
npm install -g create-react-app
Create React App (CRA) — это инструмент, который помогает создать и настроить новый проект React без необходимости ручной конфигурации. Он создает новый проект с настроенными средствами разработки, которые необходимы для создания приложения React. Это очень удобный инструмент для начинающих разработчиков, которые хотят быстро начать работу с React, и для опытных разработчиков, которые хотят сэкономить время.
Разработка логики приложения
Создадим с помощью React приложение, которое будет выводить текущую погоду в запрашиваемом городе. Добавлять стили в приложение будем с помощью плагина Tailwind.
Tailwind — это сторонний плагин для создания стилей для сайтов. Он предлагает огромный набор готовых классов для быстрой реализации дизайна, а также позволяет создавать собственные классы для уникальных дизайнов.
Погодное приложение будет содержать два основных компонента: поле для ввода города и форма с погодной информацией. Пользователь будет взаимодействовать только с полем для ввода города. Для получения данных о погоде будем использовать API.
В первую очередь собираем приложение командой create-react-app:
create-react-app weather
Эта команда создаст проект с названием Weather, который будет включать приветственное приложение. Если его запустить, то по адресу localhost:3000 вы обнаружите такое приветственное окно:
После создания проекта переходим в директорию приложения:
cd weather
Удалим ненужный код и файлы из проекта, а именно:
- полностью удалим код из файлов App.css, App.js и index.css;
- из папки public удалим логотипы React;
- из public/index.html удалим строки, связанные с логотипами React;
- из папки src удаляем setupTest.js, reportWevVitals.js и logo.svg;
- из файла index.js удаляем две строки:
import reportWebVitals from './reportWebVitals';
и
reportWebVitals();
После этого у нас останется пустой проект с необходимыми для работы файлами.
В первую очередь создадим в файле App.js класс App:
import React from "react";
import "./App.css";
class App extends React.Component{
render() {
return ();
}
}
export default App;
В блоке render() будем писать код, который хотим отобразить в окне браузера.
Создадим компонент для ввода города. Для этого создаём новую папку "components" в директории src и в ней создаем файл search.js. Подобно файлу app.js, создаем в нем новый класс Weather:
import React from "react";
class Search extends React.Component {
render() {
return();
}
}
export default Search;
И импортируем класс в App.js:
import Search from "./components/Search ";
Возвращаемся в Search.js. Создадим форму с вводом города:
import React from "react";
class Search extends React.Component {
render() {
return(
<div className="flex justify-center">
<form>
<input
type="text"
placeholder="enter city"
name="city"
className="font-light capitalize h-5 focus:outline-none"
/>
</form>
</div>
);
}
В атрибуте className описываются tailwind-свойства, которые соответствуют css-стилям. Например, в className блока input описаны следующие свойства:
- font-light — «тонкий» шрифт;
- capitalize — каждое слово, введенное в поле, будет автоматически начинаться с заглавной буквы;
- h-5 — высота поля;
- focus:outline-none — при нажатии на поле оно не будет выделяться.
Добавим в App.js класс Search и опишем основные стили приложения в атрибуте className:
import React from "react";
import "./App.css";
import Search from "./components/Search ";
class App extends React.Component{
render() {
return (
<div className={`mx-auto max-w-xs space-y-10 py-5 bg-gradient-to-br from-cyan-700 to-blue-700`}>
<Search/>
</div>
);
}
}
export default App;
Здесь className описывает следующие параметры:
- mx-auto — автоматические отступы;
- max-w-xs — максимальная ширина приложения;
- space-y-10 — вертикальное расстояние между дочерними элементами;
- py-5 — вертикальный padding;
- bg-gradient-to-br from-cyan-700 to-blue-700 — цвет фона. В данном случае градиент синего.
Если запустить приложение, то в браузере будет выведено такое окно:
Пока что оно никак не реагирует на действия от пользователя. Изменим это, реализовав API.
📜 Читайте также: Деплой React-приложения
API
Многие погодные агрегаторы предоставляют API для использования данных на сторонних ресурсах — как платные, так и бесплатные. В рамках этого материала воспользуемся сервисом Open Weather Map. Он предоставляет бесплатный API с 1000 запросов в сутки.
Для работы с API OpenWeatherMap необходимо зарегистрироваться на этом ресурсе и получить свой API-код. Его можно найти в личном кабинете после регистрации.
OpenWeatherMap возвращает на запрос ответ в json-формате:
Из этого ответа мы будем «доставать» нужную для вывода информацию. В нашем приложении это будет:
- город и страна;
- температура;
- скорость ветра;
- влажность;
- иконка погодных условий.
В файле App.js создадим функцию для получения данных о погоде и переменную state для хранения данных о погоде:
const API_KEY = "&appid=08d99c791f8d54e2c692e22cf3a2188b";
const BASE_API_URL = "https://api.openweathermap.org/data/2.5/weather?q="
class App extends React.Component{
state = {
temp: "",
city: "",
country: "",
wind: "",
humidity: "",
icon: ""
}
API_weather = async (event) => {
event.preventDefault();
const GET_URL = await fetch(BASE_API_URL+event.target.elements.city.value+API_KEY);
const response = await GET_URL.json();
this.setState({
temp: (response.main.temp - 273.16).toFixed(2),
city: response.name,
country: response.sys.country,
wind: response.wind.speed,
humidity: response.main.humidity,
icon: response.weather[0].icon
});
}
В переменной State хранятся полученные данные от OpenWeatherMap. В асинхронном методе API_weather при совершении пользовательского действия (в данном случае ввода города и нажатия Enter) осуществляется запрос по API. Полученный от сервера ответ конвертируется в json-формат.
Из полученного файла в методе setState вытаскивается нужная информация: температура, скорость ветра и т.д. После чего эти значения присваиваются элементам state.
Этот метод будет передаваться в класс Search при вызове:
render() {
return (
<div className={`mx-auto max-w-xs space-y-10 py-5 bg-gradient-to-br from-cyan-700 to-blue-700`}>
<Search API={this.API_weather}/>
</div>
);
}
В метод Search добавим вызов переданного метода API_weather при действии от пользователя. Для этого воспользуемся событием onSubmit:
<form onSubmit={this.props.API}>
<input
type="text"
placeholder="enter city"
name="city"
className="font-light capitalize h-5 focus:outline-none"
/>
</form>
Компонент вывода погоды
Создадим в директории файл weather.js и импортируем его в app.js:
import Weather from "./components/weather";
И добавим его в блок render(). Передаваемым параметром будет state:
render() {
return (
<div className={`mx-auto max-w-xs space-y-10 py-5 bg-gradient-to-br from-cyan-700 to-blue-700`}>
<Search API={this.API_weather}/>
<Weather data={this.state}/>
</div>
);
}
Переходим в weather.js и создаем в нем класс Weather для вывода информации о погоде:
import React from "react";
class Weather extends React.Component {
render() {}
}
}
export default Weather;
В первую очередь необходимо добавить проверку, ввёл ли пользователь населенный пункт. По умолчанию значения в state — пустые строки. Поэтому будем проверять, что один из элементов state не является пустой строкой:
render() {
if (this.props.data.city !== "") {
return ();
}
}
Осталось вывести все данные из state. В первую очередь будем выводить название города и страны:
render() {
if (this.props.data.city !== "") {
return (
<div className={'text-slate-50 px-3'}>
<div className={'text-xs font-light'}>{this.props.data.city}, {this.props.data.country} </div>
Все элементы этого блока будем иметь текст цвета text-slate-50 и зафиксированный padding. А название города и страны будет иметь маленький и тонкий шрифт.
Затем черед вывода температуры и погодных условий:
<div className={'text-3xl font my-3'}>
{this.props.data.temp} °C
<img src ={`http://openweathermap.org/img/w/${this.props.data.icon}.png`}/>
</div>
По ссылке загружается соответствующая погоде иконка.
Для влажности и скорости ветра также выведем соответствующие иконки из плагина @iconscout/react-unicons. Для его установки необходимо выполнить в терминале команду:
npm install --save @iconscout/react-unicons
После чего их можно импортировать в класс:
import { UilWind, UilTear } from "@iconscout/react-unicons";
Теперь можно добавить вывод информации о ветре и влажности в блок render():
<div className={'flex flex-row justify-around text-xs mt-16'}>
<div>
<UilWind></UilWind> {this.props.data.wind} m/s
</div>
<div>
<UilTear></UilTear>{this.props.data.humidity} %</div>
</div>
Так выглядит весь файл weather.js:
import React from "react";
import { UilWind, UilTear } from "@iconscout/react-unicons";
class Weather extends React.Component {
render() {
if (this.props.data.city !== "") {
return (
<div className={'text-slate-50 px-3'}>
<div className={'text-xs font-light'}>{this.props.data.city}, {this.props.data.country} </div>
<div className={'text-3xl font my-3'}>
{this.props.data.temp} °C
<img src ={`http://openweathermap.org/img/w/${this.props.data.icon}.png`}/>
</div>
<div className={'flex flex-row justify-around text-xs mt-16'}>
<div>
<UilWind></UilWind> {this.props.data.wind} m/s
</div>
<div>
<UilTear></UilTear>{this.props.data.humidity} %</div>
</div>
</div>
);
}
}
}
export default Weather;
Осталось запустить приложение и узнать, как оно работает:
Приложение работает и обрабатывает почти все города. Из-за существования одноименных населенных пунктов приложение не может получить данные о погоде в менее населенных «тезках». Это касается, например, города Saint-Petersburg в США.
Полный код нашего приложения
app.js
import React from "react";
import "./App.css";
import Weather from "./components/weather";
import Search from "./components/search";
const API_KEY = "&appid=08d99c791f8d54e2c692e22cf3a2188b";
const BASE_API_URL = "https://api.openweathermap.org/data/2.5/weather?q="
class App extends React.Component{
state = {
temp: "",
city: "",
country: "",
wind: "",
humidity: "",
icon: ""
}
API_weather = async (event) => {
event.preventDefault();
const GET_URL = await fetch(BASE_API_URL+event.target.elements.city.value+API_KEY);
const response = await GET_URL.json();
console.log(response)
this.setState({
temp: (response.main.temp - 273.16).toFixed(2),
city: response.name,
country: response.sys.country,
wind: response.wind.speed,
humidity: response.main.humidity,
icon: response.weather[0].icon
});
}
render() {
return (
<div className={`mx-auto max-w-xs space-y-10 py-5 bg-gradient-to-br from-cyan-700 to-blue-700`}>
<Search API={this.API_weather}/>
<Weather data={this.state}/>
</div>
);
}
}
export default App;
weather.js
import React from "react";
import { UilWind, UilTear } from "@iconscout/react-unicons";
class Weather extends React.Component {
render() {
if (this.props.data.city !== "") {
return (
<div className={'text-slate-50 px-3'}>
<div className={'text-xs font-light'}>{this.props.data.city}, {this.props.data.country} </div>
<div className={'text-3xl font my-3'}>
{this.props.data.temp} °C
<img src ={`http://openweathermap.org/img/w/${this.props.data.icon}.png`}/>
</div>
<div className={'flex flex-row justify-around text-xs mt-16'}>
<div>
<UilWind></UilWind> {this.props.data.wind} m/s
</div>
<div>
<UilTear></UilTear>{this.props.data.humidity} %</div>
</div>
</div>
);
}
}
}
export default Weather;
search.js
import React from "react";
class Search extends React.Component {
render() {
return(
<div className="flex justify-center">
<form onSubmit={this.props.API}>
<input
type="text"
placeholder="enter city"
name="city"
className="font-light capitalize h-5 focus:outline-none"
/>
</form>
</div>
);
}
}
export default Search;
Кстати, в официальном канале Timeweb Cloud собрали комьюнити из специалистов, которые говорят про IT-тренды, делятся полезными инструкциями и даже приглашают к себе работать.💥