React.js: собираем с нуля изоморфное / универсальное приложение. Часть 2: добавляем bootstrap, страницы и роутинг

React.js: собираем с нуля изоморфное / универсальное приложение. Часть 2: добавляем bootstrap, страницы и роутинг

Это продолжение статьи про разработку изоморфного приложения с нуля на React.js. В этой части мы добавим несколько страниц, bootstrap, роутинг, концепцию Flux и ее популярную реализацию Redux.

Оглавление

Итак, в первой части мы закончили на том, что разработали простой компонент HelloWorld и собрали окружение для сборки и контроля качества кода. Настало время сделать полноценный сайт, а это значит, что мы добавим еще несколько страниц, свяжем их ссылками и реализуем изоморфный роутинг.

1. Добавляем в проект react-bootstrap

Это очень популярная библиотека, которая позволяет использовать элементы bootstrap в стиле React.

Например, вместо конструкций вида

мы сможем писать

Также не придется использовать JavaScript-код оригинального bootstrap, ведь он уже реализован в компонентах react-bootstrap.

Устанавливаем react-bootstrap

Вносим изменения в проект

Выделим виджет HelloWorld из App.jsx в отдельный компонент. Напоминаю, что App.jsx — это точка входа в изоморфную часть приложения, и мы ее скоро перепишем в виде layout'а, внутри которого будут отображаться запрошенные пользователем страницы.

Рефакторинг
  1. Создадим папку src/components/HelloWorldPage
  2. Переименуем App.jsx в HelloWorldPage.jsx, App.css в HelloWorldPage.css
  3. Переместим файлы HelloWorldPage.jsx и HelloWorldPage.css в папку src/components/HelloWorldPage
  1. Внесем изменения в HelloWorldPage.jsx
  1. Создадим файл index.js со следующим содержанием
src/components/HelloWorldPage/index.js

Этот шаг позволит нам импортировать наш компонент так

Это аккуратнее и упрощает сопровождение исходного кода приложения.

Создаем App.jsx
  1. Создаем папку App
  2. В папке App создаем два файла: index.js и App.jsx
src/components/App/index.js src/components/App/App.jsx

Важное примечание: обратите внимание, что я явно указываю, какие компоненты react-bootstrap я импортирую. Это поможет webpack в процессе сборки включить только используемую в проекте часть react-bootstrap, а не всю библиотеку целиком, как случилось бы, если бы я написал

Важно отметить, что этот маневр работает только в тех случаях, когда используемая библиотека поддерживает модульность. Например, react-bootstrap и lodash к таким относятся, а jquery и momentjs — нет.

Как видно из кода, приведенный выше компонент не работает со state и не использует component workflow callbacks (например, componentWillMount и componentDidMount). Это означает, что его можно переписать в виде так называемого Pure Sateless Function Component.

В будущем компоненты, написанные таким образом, будут иметь преимущество в производительности (спасибо теории функционального программирования и концепции pure functions), а чем более производителен каждый компонент в отдельности, тем более производительное приложение у нас получится в итоге.

Пока же реакт оборачивает подобные компоненты в обычные ES6-классы, но с одним приятным бонусом:

По умолчанию компонент обновляется всегда при получении новых значений props и/или state даже в тех случаях, когда они полностью совпадают с предыдущими. Это не всегда необходимо. У разработчика есть возможность самостоятельно реализовать метод shouldComponentUpdate(nextProps, nextState), который возвращает либо true, либо false. С помощью него вы сами можете явно указать Реакту, в каких случаях вы хотите, чтобы компонент перерисовался, а в каких — нет.

Если же компонент реализован как Pure Stateless Function Component, то Реакт сам в состоянии определить необходимость обновления внешнего вида компонента без явной реализации shouldComponentUpdate, то есть мы получаем больший профит, приложив меньше усилий.

Примечание: код ниже является учебным примером такого компонента. Так как в будущем мы внесем изменения в App.jsx, и он перестанет быть pure stateless компонентом, не следует переносить этот пример в наш проект.

Примечание 2: в нашем проекте я буду реализовывать все компоненты в виде ES6-классов, даже там, где возможно и правильно было бы реализовать их в виде Pure Stateless Functions Components, чтобы не усложнять содержание статьи.

Самое время посмотреть, что изменилось в браузере. И… да, у bootstrap нет стилей. Разработчики react-bootstrap сознательно не включили их в дистрибутив, так как все равно вы будете использовать собственную тему. Поэтому идем на любой сайт с темами для bootstrap, например bootswatch.com, и скачиваем понравившуюся. Сохраним ее в src/components/App/bootstrap.css. Я рекомендую сохранить именно полноценную версию, так как ее проще кастомизировать, а минификацию потом все равно сделает webpack.

Примечание: можно скачать мою тему с репозитория на github.

Внесем изменение в App.jsx

src/components/App/App.jsx

Я не хочу сейчас акцентировать внимание на настройке работы с glyphicons, тем более, что мы не будем использовать их в проекте, поэтому просто удалим их из стилей.

src/components/App/bootstrap.css

Возвращаемся в браузер, и теперь все должно выглядеть хорошо.

Примечание: если при перезагрузке страницы вас раздражает, что сначала появляется старая версия страницы, а новая лишь спустя пару секунд — просто перезапустите nodemon.

📎📎📎📎📎📎📎📎📎📎