Это будет и объявлением, и объяснением. Объявление о том, что наше Приложение Accounts-UI response / redux будет открыто для публики.

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

В этом приложении около 25000 строк кода, поэтому в этой статье мы можем раскрыть только некоторые идеи. Наши самые важные решения связаны с использованием React, управлением нашим состоянием Redux, и я представлю нашу библиотеку компонентов / систему дизайна.

Прежде чем мы углубимся в подробности, возможно, вам будет полезно немного узнать о Zesty.io и о том, за что это приложение отвечает. Zesty.io - это модель SaaS WCMS (система управления веб-контентом).

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

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

Разработчики часто фыркают и ворчат, что Redux и его шаблон для большинства случаев излишни, и это не так. Чтобы его настроить, нужно немного потрудиться. Однако это всего лишь деревья, и я здесь, чтобы показать лес. Наша проблема - это данные, настойчивость и организованность. Любой, кто передал props компоненту реакции, знает, что если вам нужны данные глубже пары уровней, они могут стать, я скажу:

«Ум постоянно повторяется, чтобы непрерывно передавать эту информацию по цепочке компонентов в конечный пункт назначения данных». - Грант Глайдвелл

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

В случае нового пользователя в Zesty они создают учетную запись, подтверждают свой адрес электронной почты и входят в систему. Как только пользователь создает экземпляр и выбирает план (это шаблоны с соответствующими структурами данных для контента, готового к использованию), Обзор экземпляра открывается и позволяет пользователю редактировать несколько аспектов экземпляра. Наш магазин Redux выглядит так:

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

В других случаях, например, в случае удаления данных из магазина, это становится немного менее простым, но все же управляемым.

В mapStateToProps мы можем убедиться, что передаем только релевантную информацию каждому компоненту. Это в точности соответствует предложениям документации redux, поскольку мы нормализовали наши данные для каждого магазина, чтобы можно было легко ссылаться на них.

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

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

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

В этом дополнительном приложении необходимо только одно представление. Главное представление отвечает за получение исходных данных для команд, к которым принадлежит пользователь или для которых он был приглашен. Они вызываются в componentDidMount с помощью promise.all, поскольку наш основной элемент TeamsGrid обернут в нашWithLoader компонент, мы можем обусловить его рендеринг на те вызовы, которые возвращаются из API.

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

Наш TeamsGrid компонент отображает три других компонента: CreateTeam, который отвечает за создание команды, InviteCard, который отображает команды, к которым пользователь еще не имеет доступа, но к которым он приглашен, и TeamCard показывает, какие другие пользователи входят в команду и в каких случаях команда находится назначен.

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

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

На данный момент приложение выбрало членов моей команды для этой команды, а также экземпляры, над которыми нам поручено работать. Я нажимаю на один из экземпляров, которым моя команда назначена для отправки меня во вложенное приложение «Экземпляры». Я перехожу к обзору экземпляра для этого экземпляра, который также должен выполнять вызовы API.

Этот компонент не знает, что я только что перешел из субприложения Teams и что у меня уже есть данные команды, поэтому он ожидает, пока эта информация вернется из API для обработки.

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

Работая над этим приложением, мы смогли создать компоненты, заботясь о том, как они будут работать друг с другом, не заботясь о потоке данных.

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

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

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

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

Первоначальные вложения в архитектуру продолжают окупаться. По мере нашего прогресса мы планируем делать больше наших работ открытыми для общественности.

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