Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. React

Изучаем архитектуру Flux в React

by
Read Time:14 minsLanguages:

Russian (Pусский) translation by Masha Kolesnikova (you can also view the original English article)

Final product imageFinal product imageFinal product image
What You'll Be Creating

В этом уроке вы узнаете о технологии Flux и о том, как она используется для обработки потока данных в приложениях на основе React. Мы начнем с изучения основ Flux и понимания азов разработки приложений на его основе, а затем мы будем немного применим на практике то, чему научились, создав простое приложение для виртуального кошелька.

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

Если вы совершенно не знакомы с разработкой Реакт, я рекомендую пройти курс «Начало работы с React» Дэвида Иста, здесь, в Envato Tuts +. Это фантастический курс, который позволит вам быстро разобраться в React.

Что такое Flux?

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

Facebook сделал Flux как попытку решить проблемы, вызванные шаблоном MVC в их массивной базе кода. Они боролись с проблемами, когда действия приводили к каскадным обновлениям, что приводило к непредсказуемым результатам и коду, который становилось трудно отлаживать. Это может показаться знакомым, если раньше вы использовали MVC фреймворки, так как большинство из них по сути очень похожи. Добавьте наблюдателей и двухстороннюю привязку данных к миксу, и получите настоящую головную боль.

Мой совет - избегать любых попыток найти общий язык между Flux и MVC.  Это врятли вам чем-то поможет, и даже наоборот еще больше запутает. Flux пытается решить все по-другому, и попытка сравнить его с другими шаблонами не поможет.

Настройка проекта

Если вы хотите следовать этой статье, сначала убедитесь, что у вас установлено необходимое программное обеспечение. Когда вы закончите, клонируйте ветку boilerplate из GitHub репозитория, который я подготовил для сопровождения этой статьи.

Ниже приведены требования к программному обеспечению и версии, которые я использовал на момент написания этой статьи:

  • Git: 2.11
  • Node.js: 6.9
  • NPM: 3.10
  • Yarn: 0,22
  • Ваш редактор на выбор

Шаблон служит отправной точкой для предстоящего небольшого проекта, который мы будем создавать, небольшого приложения для виртуального кошелька. Он содержит конфигурацию Webpack для трансляции синтаксиса ES6 на простой JavaScript и WDS для обслуживания файлов. Он также имеет некоторые стили компонентов CSS, поэтому вы можете перейти сразу к работе.

Чтобы установить все необходимые зависимости, cd в каталог проекта и запустите yarn.

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

Настройка компонентов

Начните с включения следующего кода внутри js/index.js, который служит точкой входа приложения:

Для основного компонента <App/> создайте новый файл внутри js/components и назовите его App.js, и добавьте следующий код:

Компонент <App/> обертывает два других компонента: один для формы, ответственной за добавление новых элементов, а другой - за список элементов. Чтобы создать компонент <AddNewItem/>, создайте новый файл AddNewItem.js внутри js/components и добавьте этот код:

Компонент связывает некоторую логику обновления состояния при обновлении полей формы, а также некоторую базовую проверку. Давайте закончим настройку компонентов, создав последний в файле js/components/ItemsList.js для списка элементов, используя этот код:

Готово! Вы закончили настройку компонентов проекта. Большая часть состоит в том, что они также поставляются со свободным стилем.

Выполните yarn start и дождитесь, пока бандл не будет создан. Если вы откроете свой браузер на localhost:8080, вы увидите приложение без каких-либо функций.

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

Строительные блоки Flux

На высоком уровне Flux разбивается на четыре основные части: действия, диспетчер, хранилища и отображения:

  • Действия описывают действие, которое происходит в приложении.
  • Диспетчер - это однопользовательский реестр обратных вызовов. Он действует как посредник, передавая действия всем хранилищам, которые подписались на него.
  • Хранилища управляют состоянием и логикой, необходимой для его обновления для определенных частей приложения.
  • Представления - это простые старые компоненты React.

В Flux все данные передаются в одном направлении:

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

Ниже представлено визуальное представление этого процесса.

Representation of how data flows in a Flux applicationRepresentation of how data flows in a Flux applicationRepresentation of how data flows in a Flux application

Действия

Данные отправляются «по проводам» в одном направлении с использованием обычных объектов JavaScript, называемых действиями. Их задача - описать событие, которое имело место в приложении, и переносить новые данные в хранилища. Каждое действие должно иметь тип и необязательный ключ пейлоада, содержащий данные. Действие похоже на приведенное ниже:

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

Общей практикой является определение всех типов действий в объекте констант и ссылка на этот объект вместо приложения для обеспечения согласованности. Наш виртуальный кошелек будет поддерживать только одно действие, которое добавляет элементы в список - как расходы, так и финансовые выгоды будут рассматриваться как один элемент, поэтому наш файл констант будет очень простым.

Создайте файл index.js в папке js/constants и используйте следующий код для создания первого типа действия:

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

Диспетчер

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

API-интерфейс диспетчера прост и в нем доступно всего пять методов:

  • register(): регистрирует обратный вызов обработчика действия хранилища.
  • unregister(): Отменить регистрацию обратного вызова у хранилища.
  • waitFor(): Ожидает, что указанный обратный вызов (ы) запускается первым.
  • dispatch(): Выполняет действие.
  • isDispatching(): Проверяет, отправляет ли диспетчер какое-либо действие.

Наиболее важными являются register() и dispatch(), поскольку они используются для обработки большинства основных функций. Посмотрим, как они выглядят и что на самом деле происходит за кулисами.

Метод register() сохраняет все обратные вызовы в приватном массиве _callbacks, а dispatch() выполняет итерацию и вызывает каждый обратный вызов, сохраненный для принятого действия.

Для простоты мы не будем писать собственный диспетчер. Вместо этого мы будем использовать тот, который предоставляется в библиотеке от Facebook. Я рекомендую вам посмотреть репозиторий GitHub Facebook и посмотреть, как он реализован.

Внутри папки js/dispatcher создайте новый файл index.js и добавьте в него этот фрагмент кода:

Он импортирует диспетчера из библиотеки flux, которая была установлена раньше с помощью yarn , а затем экспортирует новый экземпляр.

Теперь, имея диспетчера, мы можем вернуться к действиям и настроить создателя действия нашего приложения. Внутри папки js/actions создайте новый файл walletActions.js и добавьте следующий код:

Класс WalletActions предоставляет метод addNewItem(), который обрабатывает три основные задачи:

  • Он получает item в качестве аргумента.
  • Он использует диспетчера для отправки действия с типом действия ADD_NEW_ITEM, который мы уже создали ранее.
  • Затем он отправляет полученный item в качестве пейлоада вместе с типом действия.

Прежде чем использовать этот создатель действия, давайте посмотрим, что такое хранилища и как они вписываются в наше Flux-приложение.

Хранилища

Я знаю, я сказал, что вы не должны сравнивать Flux с другими шаблонами, но хранилища Flux похожи на модели в MVC. Их роль заключается в обработке логики и хранении состояния для определенного компонента верхнего уровня в вашем приложении.

Все хранилища Flux должны определить метод обработчика действий, который затем будет зарегистрирован диспетчером. Эта функция обратного вызова в основном состоит из оператора switch для полученного типа действия. Если выполняется конкретный тип действия, он действует соответствующим образом и обновляет локальное состояние. Наконец, хранилище передает событие, чтобы сигнализировать представления об обновленном состоянии, чтобы они могли соответствующим образом его обновлять.

Чтобы транслировать события, хранилища должны расширять логику эмиттера событий. Существуют различные библиотеки эмиттеров событий, но наиболее распространенным решением является использование эмиттера событий Node. Для простого приложения, такого как виртуальный кошелек, нет необходимости в более чем одном хранилище.

Внутри папки js/stores создайте новый файл walletStore.js и добавьте следующий код для хранилища:

Мы начинаем с импорта необходимых зависимостей, необходимых для хранилища, начиная с емиттера события Node, диспетчера, за которым следуют ActionTypes. Вы заметите, что под ними есть константа CHANGE, похожая на типы действий, о которых вы узнали ранее.

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

При инициализации класс WalletStore начинается с регистрации обратного вызова _registerToAction() в диспетчере. За кулисами этот обратный вызов будет добавлен в массив _callbacks диспетчера.

Метод имеет один оператор switch над типом действия, полученным от диспетчера при отправке действия. Если он соответствует типу действия ADD_NEW_ITEM, то затем запускается метод _addNewItem() и ему передается полученный пейлоад.

Функция _addNewItem() устанавливает id для элемента, добавляет его к списку существующих элементов и затем запускает событие CHANGE. Далее методы getAllItems() и getTotalBudget() являются базовыми геттерами, которые мы будем использовать для извлечения состояния текущего хранилища и общего бюджета.

Последние два метода addChangeListener() и removeChangeListener() будут использоваться для связывания компонентов React с WalletStore, чтобы они получали уведомление при изменении данных хранилища.

Представления контроллеров

Использование React позволяет разбить части приложения на различные компоненты. Мы можем их встраивать и построить интересные иерархии, которые формируют рабочие элементы на нашей странице.

В Flux компоненты, расположенные в верхней части цепочки, имеют тенденцию хранить большую часть логики, необходимой для создания действий и получения новых данных; Поэтому они называются представлениями контроллера. Эти представления напрямую подключаются к хранилищам и прослушивают события изменений, вызванные при обновлении хранилищ.

Когда это происходит, просмотры контроллера вызывают метод setState, который запускает метод render() для запуска и обновления представления и отправки данных дочерним компонентам через props. Затем React и Virtual DOM делают свою магию и максимально обновляют DOM.

Наше приложение достаточно простое и не соблюдает это правило. Однако в зависимости от сложности более крупные приложения иногда могут потребовать несколько представлений контроллера с вложенными подкомпонентами для основных частей приложения.

Соберем все вместе

Мы закончили рассмотрение основных частей Flux, но приложение виртуального кошелька еще не завершено. В этом последнем разделе мы рассмотрим весь поток от действий к представлениям и добавим недостающий код, необходимый для завершения однонаправленного потока данных Flux.

Отправка действия

Возвращаясь к компоненту <AddNewItem/>, теперь вы можете включить модуль WalletActions и использовать его для генерации нового действия в методе _addNewItem().

Теперь, когда форма отправлена, отправляется действие, и все хранилища - в нашем случае - уведомляются о новых данных.

Прослушивание изменений в хранилище

В вашем WalletStore, в настоящий момент, когда элемент добавляется в список, его состояние изменяется, а событие CHANGE запускается, но его пока что еще никто не слушает. Давайте закроем цикл, добавив слушателя изменений внутри компонента <ItemsList/>.

Обновленный компонент закрывает поток однонаправленных потоков Flux. Обратите внимание, что я пропустил включение метода render(), чтобы сохранить немного места. Давайте пройдем все шаг за шагом:

  • Вверху включается модуль WalletStore.
  • Исходное состояние обновляется, чтобы вместо этого использовать состояние хранилища.
  • Новый метод _onChange() используется для обновления состояния новыми данными из хранилища.
  • Используя хуки жизненного цикла React, обратный вызов _onChange() добавляется и удаляется в качестве обратного вызова прослушивателя изменений в хранилище.

Заключение

Мои поздравления! Вы закончили создание рабочего приложения для виртуального кошелька на базе Flux. Вы узнали, как все компоненты Flux взаимодействуют друг с другом и как вы можете использовать эту структуру для создания своих собственных приложений.

Когда вы почувствуете уверенность в своих навыках Flux, убедитесь, что вы также ознакомились и с другими реализациями Flux, такими как Alt, Delorean, Flummox или Fluxxor и посмотрите, какой из них вам больше подходит.

Дайте мне знать ваши мысли в комментариях ниже, я хотел бы узнать, что вы думаете о Flux или помочь, если у вас возникли трудности после этого учебника. Если вы хотите, вы также можете связаться со мной в Twitter @hiskio.

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.