В этой статье вы познакомитесь с React — библиотекой для создания пользовательских интерфейсов. React появился в 2013 году и достаточно быстро стал популярным среди разработчиков. Сегодня в работе над веб-приложениями его используют Facebook, Instagram, Trello, AirBnb, PayPal. С помощью этой статьи мы сможем написать приложение прогноза погоды: от установки с помощью create-react-app
(проект на GitHub) до подключения API и стилей bootswatch.
Прим. перев. Если вы начинаете изучение React, вам также стоит прочитать наш материал, в котором разработчик делится советами по использованию этой библиотеки.
Этот материал был написан для воркшопа Open Source Dev Garage, прошедшего в рамках конференции разработчиков F8 2017. Чтобы лучше разобраться в том, как написать это приложение, посмотрите 48-минутное видео или следуйте письменным инструкциям в этом руководстве.
Просмотрев семинар или изучив руководство, вы создадите простое приложение прогноза погоды:
Итак, приступим.
Создайте ваше первое приложение
Прежде всего вам понадобится node.js и редактор кода, например, Atom.
Откроем терминал и установим create-react-app
:
npm install -g create-react-app
Примечание: Пользователям Linux или MacOS, возможно, потребуется дополнительно ввести команду
sudo
передnpm install -g
.
Начнем создавать наше приложение прогноза погоды:
create-react-app weather
Данной командой мы установим набор инструментов, которые помогут создать наше React-приложение. По завершении установки мы сможем запустить приложение командами:
cd weather
npm start
Новое приложение автоматически откроется в браузере!
Свойства и компоненты
Давайте взглянем на приложение, которое create-react-app
создал автоматически. В редакторе кода откроем weather/src/App.js
:
class App extends Component {
render() {
return (
<div className="App">
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Welcome to React</h2>
</div>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
</p>
</div>
);
}
}
Наше приложение состоит из одного компонента, где функция render()
является его главной составляющей. Напишите какой-нибудь текст, сохраните изменения и посмотрите, как приложение автоматически применит их!
Теперь создадим новый компонент WeatherDisplay
. Так как функция render()
— это «сердце» компонента, то именно она определяет, что будет отображено. Для начала создадим тег с каким-нибудь текстом внутри:
class WeatherDisplay extends Component {
render() {
return (
<h1>Displaying some Weather!</h1>
);
}
}
Изменим компонент App
, чтобы отобразить наш WeatherDisplay
:
class App extends Component {
render() {
return (
<div className="App">
<WeatherDisplay zip={"12345"} />
</div>
);
}
}
Как видите, мы передали данные, которые обозначили переменной zip
, в компонент WeatherDisplay
. Они называются свойствами (props). Мы можем модифицировать наш компонент для отображения передаваемых данных:
class WeatherDisplay extends Component {
render() {
return (
<h1>Displaying weather for city {this.props.zip}</h1>
);
}
}
Где-нибудь в начале файла добавим несколько городов, для которых мы хотели бы отобразить погоду:
const PLACES = [
{ name: "Palo Alto", zip: "94303" },
{ name: "San Jose", zip: "94088" },
{ name: "Santa Cruz", zip: "95062" },
{ name: "Honolulu", zip: "96803" }
];
Обновим render()
в компоненте App
, в котором, перебирая массив PLACES
, создадим тег button
для каждого города:
return (
<div className="App">
<WeatherDisplay zip={"12345"} />
{PLACES.map((place, index) => (
<button
key={index}
onClick={() => {
console.log('Clicked index '+index);
}}
>
{place.name}
</button>
))}
</div>
);
Из массива данных мы создадим набор элементов button
и назначим свойство key
для каждого, чтобы React знал последовательность элементов в массиве.
Здесь также есть обработчик событий onClick
, который при нажатии будет выводить сообщение в консоль браузера. Открыв панель разработчика в браузере, вы можете увидеть логи событий. Ваше приложение должно выглядеть так:
На этом этапе файл App.js
должен выглядеть так.
Состояние
Мы хотим, чтобы в приложении была возможность переключаться между местами, поэтому мы можем использовать состояние (state
) для хранения данных в компоненте App
.
Сначала давайте добавим функцию-конструктор, в которой будет использоваться super()
, а затем установим начальное состояние this.state
:
constructor() {
super();
this.state = {
activePlace: 0,
};
}
Функция render()
может брать данные из this.state
при составлении пользовательского интерфейса. Для этого мы можем использовать метод setState
компонента React, который меняет состояние и перезапускает функцию render()
, чтобы изменить пользовательский интерфейс.
Применим this.state
и this.setState
в нашем компоненте App
:
class App extends Component {
constructor() {
super();
this.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.name}
</button>
))}
<WeatherDisplay
key={activePlace}
zip={PLACES[activePlace].zip}
/>
</div>
);
}
}
На этом этапе файл App.js
должен выглядеть так.
Жизненный цикл компонентов и выборка данных
Иногда нам нужно добавить императивный код (React-код обычно декларативен), который вызывается в определенное время жизни компонента. Методы жизненного цикла позволяют нам написать дополнительный код как раз для таких случаев.
В этом примере мы хотим вызвать API, когда компонент загрузится на экране, для этого добавим код в componentDidMount
. Обновим компонент WeatherDisplay
:
class WeatherDisplay extends Component {
constructor() {
super();
this.state = {
weatherData: null
};
}
componentDidMount() {
const zip = this.props.zip;
const URL = "http://api.openweathermap.org/data/2.5/weather?q=" +
zip +
"&appid=b1b35bba8b434a28a0be2a3e1071ae5b&units=imperial";
fetch(URL).then(res => res.json()).then(json => {
this.setState({ weatherData: json });
});
}
render() {
const weatherData = this.state.weatherData;
if (!weatherData) return <div>Loading</div>;
return <div>{JSON.stringify(weatherData)}</div>;
}
}
Улучшим вывод render()
для красивого вывода данных:
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}°</p>
<p>High: {weatherData.main.temp_max}°</p>
<p>Low: {weatherData.main.temp_min}°</p>
<p>Wind Speed: {weatherData.wind.speed} mi/hr</p>
</div>
);
На этом этапе файл App.js
должен выглядеть так.
Установка компонентов
Наше приложение всё еще выглядит не очень красиво. Можно исправить это, добавив className
(из стилей CSS) в свойства div
или установив соответствующую библиотеку с помощью npm
.
Bootstrap — популярный набор инструментов для стилизации пользовательского интерфейса в HTML и CSS. Установим его вместе с react-bootstrap
, который предоставляет компоненты React для bootstrap
:
npm install --save bootstrap react-bootstrap
Импортируем стили из bootstrap
в начале файла:
import "bootstrap/dist/css/bootstrap.css";
Далее импортируем из react-bootstrap
компоненты, которые мы хотим использовать. Их можно найти на сайте react-bootstrap:
import { Navbar, NavItem, Nav, Grid, Row, Col } from "react-bootstrap";
Заменим теги в компоненте App
, чтобы вывести компоненты bootstrap
:
<div>
<Navbar>
<Navbar.Header>
<Navbar.Brand>
React Simple Weather App
</Navbar.Brand>
</Navbar.Header>
</Navbar>
<Grid>
<Row>
<Col md={4} sm={4}>
<h3>Select a city</h3>
<Nav
bsStyle="pills"
stacked
activeKey={activePlace}
onSelect={index => {
this.setState({ activePlace: index });
}}
>
{PLACES.map((place, index) => (
<NavItem key={index} eventKey={index}>{place.name}</NavItem>
))}
</Nav>
</Col>
<Col md={8} sm={8}>
<WeatherDisplay key={activePlace} zip={PLACES[activePlace].zip} />
</Col>
</Row>
</Grid>
</div>
Теперь наше приложение выглядит привлекательнее, но будет здорово, если мы добавим что-то от себя. Для этого установим bootswatch
:
npm install --save bootswatch
Выберите подходящее оформление на сайте bootswatch и установите его, заменив bootstrap
. В нашем примере мы используем тему journal:
import "bootswatch/journal/bootstrap.css";
Окончательный вид нашего приложения:
Окончательный вариант App.js
.
Развертывание (дополнительный материал)
Прежде всего опубликуйте ваш код на Github, затем перейдите в ваш репозиторий и откройте файл ReadMe, в котором вы найдете инструкцию по развертыванию приложения на различных популярных сервисах.
Одним из таких сервисов является Netlify, особенно в случае, когда вы хотите использовать механизм «непрерывного развертывания».
Полезные материалы для изучения React и дальнейшей работы с ним
- React Native: используйте React для создания мобильных приложений.
- Redux: инструмент для управления данными в больших приложениях.
- Relay: библиотека для связи компонентов React и данных GraphQL.
- Jest: фреймфорк для тестирования JS-кода.
- Flow: инструмент для статической проверки типов.
Перевод статьи «Intro To React Workshop»