Apeiron
RU UA EN

IT технологии: Flux React

12 авг. 2021 г., 13:13:30

Содержание статьи:

Flux React tutorial: главные особенности и преимущества Flux application architecture

Итак, что такое Flux? Он представляет собой Flux application architecture, применяемую в Facebook во время разработки на «Реакте». Речь идет не о фреймворке, а об особом Flux application architecture подходе, позволяющем эффективно дополнять React, а также оптимизировать однонаправленный поток.

Facebook Flux располагает репозиторием с реализацией Dispatcher. Он посредничает между «Издателем» и «Подписчиком» и отправляет нужную информацию обработчикам.

Стандартная реализация Flux способна воспользоваться этой библиотекой совместно с EventEmitter из NodeJS для построения системы, позволяющей руководить состоянием приложения.

Проще всего показать, что такое Flux, описав его компоненты:

  1. Actions (Действия). Облегчающие отправку информации хелперы.
  2. Dispatcher (Диспетчер). Принимает Actions и пересылает нагрузку обработчикам.
  3. Stores (Хранилище). Контейнер для логики и состояния приложения.
  4. Controller Views (Представления). Компоненты Flux Reactjs, аккумулирующие состояние Stores и способные делиться им с дочерними элементами благодаря собственным свойствам.

Таким образом, процесс можно отразить с помощью диаграммы:

Flux компоненты

Какое отношение к этому имеет API? Применение Actions для отправки данных в Store посредством потока Flux — наиболее удачный метод обработки данных, которые поступают в приложение извне или передаются наружу.

Flux dispatcher

Dispatcher — менеджер данного процесса, выполняющий роль главного узла приложения. Он принимает входящие Actions, после чего рассылает их (и относящуюся к ним информацию) всем зарегистрированным в Dispatcher обработчикам.

Впрочем, Flux dispatcher не совсем pub/sub. Он отсылает информацию всем без исключения обработчикам, позволяет их вызывать в нужном порядке и даже ждет обновления, прежде чем продолжать свою работу. Dispatcher всего один, является центральным узлом приложения.

Один из вариантов работающего в architecture Flux Dispatcher:

Dispatcher Flux

В приведенном примере Flux React tutorial используется Dispatcher- экземпляр вместе с методом handleViewAction. Данная абстракция удобна для расчленения тех действий, которые были созданы в интерфейсе, и тех, что пришли с сервера/API.

handleViewAction вызывает еще один метод — dispatch, отсылающий action-информацию обработчикам. В случае обработки данного действия внутри Stores состояние приложения обновляется.

Эта диаграмма служит иллюстрацией описанного выше процесса в architecture Flux:

Архитектура Flux

Одно из преимуществ данной реализации Flux dispatcher — указание зависимостей и руководство по очередности отработки обработчиков в Store. В случаях, когда правильное отображение состояния какого-то компонента находится в зависимости еще от одного, который обязан претерпеть обновление раньше первого, потребуется метод waitFor.

Чтобы воспользоваться такой возможностью, в свойстве Store под названием dispatcherIndex следует сохранить возвращаемое регистрационным Dispatcher-методом значение:

ShoeStore.dispatcherIndex = AppDispatcher.register(function(payload) { });

После этого в Store для обработки Action применяется waitFor, позволяющий убедиться, что ShoeStore уже отработал Action, обновив нужную информацию:

waitFor в Store

Примечание переводчика: Ken Wheeler, скорее всего, опирается на устаревший вариант Dispatcher, поскольку в его текущей версии waitFor имеет видоизмененную сигнатуру.

Stores

Во Flux architecture Stores отвечают за управление состоянием отдельных частей предметной области приложения. Это значит, что они хранят информацию, методы ее получения и Actions-обработчики.

Наиболее примечательным моментом, который представлен в этом примере Flux React tutorial, является включение в Store функции EventEmitter из NodeJS. Она дает возможность им прослушивать и отсылать события. Это позволяет компонентам Controller Views производить обновление на основе этих событий. Поскольку этот Controller Views отслеживает создаваемое в Store событие change, он сразу же узнает об изменении состояния приложения и отображает актуальное состояние.

Кроме того, с помощью метода register в AppDispatcher был зарегистрирован обработчик. После этого Store может принимать сообщения от AppDispatcher. На основе полученной информации оператор switch определяет, сможет ли обработать Action. Если да, то после обработки создается change-событие, а подписанные на него Controller Views обновляют свое состояние.

Controller View применяет метод getShoes Store-интерфейса для получения всех shoes из внутреннего объекта _shoes и дальнейшей передачи информации в компоненты. Столь незамысловатый образец Flux architecture дает возможность компонентам оставаться аккуратными даже в том случае, если вместо Controller Views используется более сложная логика.

Action Creators & Actions

Action Creators — список методов, вызываемых из Controller Views для отправки Actions в направлении Dispatcher. Actions — та самая нагрузка, рассылаемая подписчикам Dispatcher.

В Facebook Flux все Actions отличаются по типу, роль которого играет константа, отсылаемая наряду с самими Actions. Последние, в зависимости от типа, обрабатываются нужным образом. Данные из Actions служат аргументами для внутренних методов.

Как выглядит объявление константы в architecture Flux:

Данные из Actions

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

Пример объявления Action Creators:

Пример объявления Action Creators

В показанном примере внутри объекта ShoeStoreActions создается метод, передающий Dispatcher вышеуказанные данные. После этого файл можно подгрузить из требуемого API/Controller View и вызвать метод ShoeStoreActions.loadShoes(ourData) для пересылки полезной нагрузки в направлении Dispatcher. Тот, в свою очередь, отсылает ее подписчикам. ShoeStore видит созданное событие и вызывает метод загрузки каких-либо shoes.

Controller Views

Controller Views являются React-компонентами, отслеживающими change-событие и получающими из Stores состояние приложения. После этого они отправляют полученные данные дочерним компонентам с помощью свойств.

Пример:

Controller Views являются React-компонентами

Примечание переводчика: в текущей версии React создание компонентов осуществляется немного по-другому.

В вышеприведенном примере выполняется подписка на обновления Store благодаря addChangeListener, после чего состояние обновляется каждый раз после формирования change-события.

Состояние приложения сохраняется в Stores, а потому для получения данных и обновления состояния компонентов используется именно их интерфейс.

Собираем все вместе с применением Flux pattern

Только детальное изучение архитектуры Flux может дать полноценное понимание того, что такое Flux и как он работает. Поэтому теперь, когда функции всех элементов потока более-менее ясны, стоит внимательнее рассмотреть диаграмму процессов.

Действие Flux architecture на примере

Самое время увидеть, что такое Flux, на конкретном примере. Для этого нужно создать новый проект, выделив на него каталог fluxapp. Сначала добавляется package.json.

Помимо зависимостей react-dom и react, тут добавляется еще и flux reactjs-зависимость. Поскольку приложение в итоге разбивается на несколько отдельных частей, для их компиляции и сборки в соответствии с Flux pattern используются webpack- и babel-пакеты.

После этого в терминале необходимо выполнить npm install. Эта команда открывает нужный каталог и устанавливает требуемые пакеты.

Следующим этапом нужно определить index.html.

Все файлы компилируются в public/bundle.js, подключаемый на web-странице.

Для логики с применением React в проекте открывается новая папка с именем app. Сперва необходимо определиться с Actions, выполнение которых будет доступно приложению. В приведенном примере речь идет об элементарном приложении, руководящем целым списком объектов путем их удаления и добавления. По этой причине в app следует добавить каталог под названием data. В нем будет храниться ActionTypes.js:

const ActionTypes = { ADD_ITEM: "ADD_ITEM", REMOVE_ITEM: "REMOVE_ITEM"}; export default ActionTypes;

Тут определены два вида действий. После этого в папку app/data нужно добавить PhonesDispatcher.js. В нем будет храниться определение Dispatcher:

import {Dispatcher} from "flux"; export default new Dispatcher();

Dispatcher — объект Dispatcher-класса из flux-пакета.

Дальнейший этап заключается в добавлении в папку app/data файла Actions.js.

Он будет определять Actions. Все они представляют собой функции, в которые можно передавать параметры. На этом этапе перечень объектов представляет собой простой набор строк, в связи с чем в действия удаления и добавления элементов отправляется строка с добавляемым или удаляемым объектом.

При этом внутри Action вызывается dispatch-метод. Параметром для него служит объект с типом Action и самой передаваемой информацией. В принципе, в объекте можно передать любые необходимые данные. После вызова Action данный объект отправляется в Store.

Теперь в папке app/data для Store определяется PhoneStore.js

Store — это класс, который является наследником ReduceStore-класса из flux/utils-пакета. Объект Dispatcher отправляется в конструктор базового класса через Store-конструктор.

Благодаря методу getInitialState() устанавливается состояние последнего. В этом случае речь идет о списке — объекте Immutable.List. За исключением того, что список неизменяемый, а операции с ним возвращают его новую обновленную версию, он идентичен javascript-массиву. Детальнее о работе с подобными коллекциями можно узнать на https://facebook.github.io/immutable-js.

Унаследованный метод reduce() получает объекты state (содержит информацию об актуальном состоянии Store, изначально возвращаемом getInitialState) и action (передается в Action и определяет его тип, то есть указывает на добавление или удаление элемента). При помощи switch-конструкции можно выяснить, какое вызывается действие, и, ориентируясь на тип Action, выполнить удаление или добавление элемента.

Собственно, это вся логика для работы с данными приложения. Настал черед его визуальной составляющей. Следуя Flux pattern, для этого в каталоге app нужно создать папку views с файлом AppView.js

Список смартфонов

Класс AppView — высокоуровневый компонент, выводящий список, под каждый элемент которого выделен отдельный Phone-компонент. Их тоже можно разместить в специальные файлы, однако в данном примере они помещены в один для упрощения его восприятия.

Для объединения Stores, Actions и Controller Views Flux архитектура использует контейнеры: в app создается подкаталог containers, в который и вставляется файл AppContainer.js:

Контейнерный класс AppContainer является React-компонентом, реализующим два важных метода: getStores() и calculateState().

getStores() возвращает список используемых приложением Stores. В приведенном примере это PhoneStore.

calculateState() возвращает контейнерное состояние. Тут в него входит список phones, который можно получить из состояния Store.

Таким образом, phones содержат Immutable.List.

Кроме того, состояние определяет два следующих действия:

Они наряду с phones отправляются в AppView, создающийся в render-методе. Так что Controller View становится взаимосвязанным в AppView со Stores и Actions, а благодаря обработчикам кнопок может вызывать те или иные Actions.

В конце файла расположен Container.create(AppContainer) — метод для создания контейнера. Последний загружается в app.js из каталога app:

После этого в корневой каталог проекта добавляется webpack.config.js. На нем будет лежать задача объединить все файлы в единую сборку:

В результате проект на Reactjs and Flux будет выглядеть так:

Чтобы выполнить компиляцию и файловую упаковку, требуется открыть терминал, зайти в корневую папку и выполнить npm run build. После этого сгенерируется public/bundle.js, который нужен для подключения на web-странице.

В самом конце для запуска проекта понадобится выполнить npm run dev.

Заключение

Цель статьи доступно объяснить, что такое Flux, а также как устроена и работает его Flux архитектура. Даже если всего раз воспользоваться Flux, отчетливо понимаешь, что писать на «Реакте» без него то же самое, что манипулировать с DOM без jQuery. Само собой, это реально, однако Flux architecture React смотрится куда более упорядоченно.

Если есть желание воспользоваться всеми преимуществами Flux architecture, но без применения React, подойдет Delorean. Это Flux-фреймворк, совместимый с Ractive.js либо Flight. Другой интересной библиотекой является Fluxxor, который исповедует несколько иной подход к Flux architecture и обеспечивает более жесткую взаимосвязь между компонентами Flux внутри единого экземпляра. Flux architecture Redux является еще одним примером использования Flux-подобной архитектуры.

Лучший способ понять, что такое Flux, и оценить все преимущества Flux architecture React — опробовать его на практике. Поэтому при случае обязательно стоит испытать его в деле!

Вакансии с технологией Flux

Для поиска вакансий на сайте Apeirondb.com вам всего лишь в разделе с вакансиями нужно выбрать город, страну и технологию, которые вас интересуют: Технология Flux. А также, очень легко осуществить поиск при помощи телеграм бота HIRE:bot(t.me/hireIT_bot) @hireIT_bot, который при правильной настройке, будет отправлять вам только вакансии с технологией React Native.

Полезные ссылки