Написать пост

Пишем полноценное приложение на React с нуля за час

Аватар Егор Мадьяров

В этой статье вы познакомитесь с React — JavaScript-библиотекой для создания пользовательских интерфейсов. Вы напишете приложение прогноза погоды с нуля.

Обложка поста Пишем полноценное приложение на React с нуля за час

В этой статье вы познакомитесь с React — библиотекой для создания пользовательских интерфейсов. React появился в 2013 году и достаточно быстро стал популярным среди разработчиков. Сегодня в работе над веб-приложениями его используют Facebook, Instagram, Trello, AirBnb, PayPal. С помощью этой статьи мы сможем написать приложение прогноза погоды: от установки с помощью create-react-app (проект на GitHub) до подключения API и стилей bootswatch.

Прим. перев. Если вы начинаете изучение React, вам также стоит прочитать наш материал, в котором разработчик делится советами по использованию этой библиотеки.

Этот материал был написан для воркшопа Open Source Dev Garage, прошедшего в рамках конференции разработчиков F8 2017. Чтобы лучше разобраться в том, как написать это приложение, посмотрите 48-минутное видео или следуйте письменным инструкциям в этом руководстве.

Просмотрев семинар или изучив руководство, вы создадите простое приложение прогноза погоды:

Пишем полноценное приложение на React с нуля за час 1

Итак, приступим.

Создайте ваше первое приложение

Прежде всего вам понадобится 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
		

Новое приложение автоматически откроется в браузере!

Пишем полноценное приложение на React с нуля за час 2

Свойства и компоненты

Давайте взглянем на приложение, которое 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, который при нажатии будет выводить сообщение в консоль браузера. Открыв панель разработчика в браузере, вы можете увидеть логи событий. Ваше приложение должно выглядеть так:

Пишем полноценное приложение на React с нуля за час 3

На этом этапе файл 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>
    );
  }
}
		
Пишем полноценное приложение на React с нуля за час 4

На этом этапе файл App.js должен выглядеть так.

Жизненный цикл компонентов и&nbsp;выборка данных

Иногда нам нужно добавить императивный код (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>
);
		
Пишем полноценное приложение на React с нуля за час 5

На этом этапе файл 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>

		
Пишем полноценное приложение на React с нуля за час 6

Теперь наше приложение выглядит привлекательнее, но будет здорово, если мы добавим что-то от себя. Для этого установим bootswatch:

			npm install --save bootswatch
		

Выберите подходящее оформление на сайте bootswatch и установите его, заменив bootstrap. В нашем примере мы используем тему journal:

			import "bootswatch/journal/bootstrap.css";
		

Окончательный вид нашего приложения:

Пишем полноценное приложение на React с нуля за час 7

Окончательный вариант App.js.

Развертывание (дополнительный материал)

Прежде всего опубликуйте ваш код на Github, затем перейдите в ваш репозиторий и откройте файл ReadMe, в котором вы найдете инструкцию по развертыванию приложения на различных популярных сервисах.

Одним из таких сервисов является Netlify, особенно в случае, когда вы хотите использовать механизм “непрерывного развертывания”.

Полезные материалы для изучения React и&nbsp;дальнейшей работы с&nbsp;ним

  • React Native: используйте React для создания мобильных приложений.
  • Redux: инструмент для управления данными в больших приложениях.
  • Relay: библиотека для связи компонентов React и данных GraphQL.
  • Jest: фреймфорк для тестирования JS-кода.
  • Flow: инструмент для статической проверки типов.
JavaScript
Для начинающих
Веб-разработка
Обучение программированию
F8 2017
React
Фронтенд
180610