(Автор Алекс Синельников)

Сегодня я хотел бы поговорить об использовании React.js и RoR в одном приложении, где оба рендерят интерфейс. С такой необходимостью я столкнулся, работая над недавним проектом. У меня была форма со многими прикрепленными функциями, и она выглядела так, но размножалась в течение 7 дней.

Первоначально этим управлял jQuery. Любое обновление любого поля создавало запрос на сервер с информацией обо всех полях. Таким образом, все могло бы работать так, если бы только клиенты не хотели добавлять возможность изменять или удалять сущности. Но дальнейшая разработка с помощью jQuery была сложной из-за того, что мне приходилось справляться со многими вещами. Я попробовал несколько js-фреймворков и решил запустить React. Во-первых, я немного растерялся, так как не знал, с чего начать: либо совмещать вебпак с ассет-пайплайном, либо паковать вручную на сервере перед деплоем.

Как обычно, я начал гуглить любое существующее решение и нашел два почти одинаковых драгоценных камня с единственным отличием. Один из них не умел работать с npm и ограничивался только стандартными инструментами. Так что я предпочел еще одну жемчужину React on rails. Установка была довольно простой — Gemfile и конфигуратор. После этого давайте перейдем к написанию кода React.js. Все файлы хранятся в папке /client, как и конфигуратор webpack.

Я хочу обратить ваше внимание на файл /config/app/app.js. В моем случае это выглядит так:

import ReactOnRails from 'react-on-rails';
import WorkingHourList from './components/working_hours/WorkingHourList.jsx';
import WorkingDay from './components/working_hours/WorkingDay.jsx'
ReactOnRails.register({
WorkingHourList, WorkingDay
});

Это гем-способ оборачивать данные и передавать их в Rails, чтобы информировать Rails о компонентах пользовательского интерфейса. После того, как компоненты «зарегистрированы», мы можем использовать их в наших представлениях Rails, например:

.col-md-12.table-clock.table-with-schedule
.row
= react_component("WorkingHourList", props: { working_hours: @working_hours, sales_rep_id: @rep.id }, prerender: true)

Я хочу выделить флаг prerender: true. Если установить значение true, компонент будет отображаться на сервере. Почему я его использовал? Ответ прост. Мой компонент был создан в модальном режиме, запрошенном через remote: true. Конечно, вы можете рендерить и на клиенте, это на ваше усмотрение.

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

ReactOnRails.reactOnRailsPageLoaded();

Этот код инициализирует компоненты React.js и делает всю магию для рендеринга и другой логики для компонента. Теперь вам нужно только написать свои компоненты и использовать их.

Как видите, это довольно просто, но в то же время с гибридным подходом вы можете избежать написания большого количества кода jQuery и получить больше контроля над своим приложением. Этот код инициализирует компоненты React.js и делает всю магию с рендерингом и прочим логика компонента. Теперь вам нужно только написать свои компоненты и использовать их.

И последнее, но не менее важное: вы можете отправлять данные из базы данных непосредственно в реагирующее приложение, что снижает нагрузку на сервер, несущественные запросы и кодирование как на сервере, так и на клиенте. Дальнейшие действия зависят от потребностей и целей проекта. Вы можете перемещать весь динамический интерфейс, чтобы реагировать с минимальными усилиями.

Удачи!