MobX хранит определения в реальном приложении

В этом посте показана сторона Управление состоянием на timefic.com, что означает, что мы не говорим здесь о компонентах React, рендеринге в dom или обработке пользовательских событий. Речь пойдет о том, как организовать данные (состояние) и как смоделировать любое приложение на основе трех типов или семейств магазинов:

  • Магазины утилит: магазины, которые являются «архитектурными» для приложения (и, вероятно, приложения, которое вы создаете сейчас), поэтому они могут использоваться всеми модулями или службами, определенными в вашей «общей картине».
  • Местные магазины: магазины, которые сохраняются локально или не сохраняются вообще. Они содержат временные данные, но имеют решающее значение для работы ваших пользователей на стороне клиента.
  • Магазины доменов: магазины, относящиеся к определенному домену или услуге и в которых действуют бизнес-правила.

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

Магазин №1: Корневой магазин

AKA: мать всех магазинов

Создавая свои первые магазины, вы постепенно добавляете туда все необходимые функции, например:

  • Добавьте поля (наблюдаемые), которые потребуются большинству хранилищ, например dbData (данные, поступающие с вашего сервера) и готово (логическое значение, указывающее, что эти данные уже загружены).
  • Выполните вызов на сервер, чтобы заполнить необходимые данные.
  • Создайте общее действие под названием изменить, чтобы изменить значение любого поля (наблюдаемого), которое вы объявляете.
  • Зарегистрируйте каждое хранилище в объекте окна, например: window.ActionsStore.
  • Инициализируйте хранилище данными вместо загрузки данных с вашего сервера (полезно, например, при тестировании системы).

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

Магазин # 2: Магазин чеков

AKA: Швейцар.

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

В моем случае я прошел 3 этапа, чтобы решить эту проблему:

  • Проверка на уровне действия: действие отправляется по мере ввода пользователем (событие onChange) или отправки поля (событие onClick). Действие принимает этот ввод, но перед переходом на серверную часть проверяет, хорошо ли выглядит письмо. Это нормально, пока вам не понадобится подтвердить электронную почту в другом месте: собираетесь ли вы снова писать тот же код?
  • Проверка с помощью служебной функции: нет, вы знаете, что не сможете жить с этим очевидным дублированием кода (и вы знаете, что в будущем будет утроение…). Таким образом, вы создаете служебные функции с именами checkEmail, checkPassword, checkToken и т. Д. Это хорошо, здесь нет дублирования, но вам нужно сохранить результат где-нибудь об этой проверке, не так ли?
  • Подтвердить с помощью магазина: наш друг, магазин появляется. Он будет не только содержать написанные вами служебные функции (хорошо, если функция имеет дом), но также будет хранить данные, которые возвращаются в результате проверок, которые вы выполняете. Итак, компонент React может наблюдать за этими данными и показывать пользователю приятное сообщение (также определенное в магазине!). Наконец, поскольку эта ошибка не должна быть видна вечно, вы также определите стандартный механизм ее исчезновения: например, тайм-аут.

Магазин №3: Магазин предупреждений

Также известен: средство повышения удобства использования.

Похожая история, чем у Checks Store.

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

Второй после отправки этих действий он спросит себя: Я отправил его? Получил ли он? После того, как Whatsapp изобрел одинарный и двойной убедитесь, что вы знаете, что пользователи ожидают немедленной реакции на определенные действия (пожалуйста, не на каждое действие!).

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

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

Например: в timefic я сделал выбор, чтобы все Checks Stores были точной копией магазина утилит, потому что я решил, что его использование является «универсальным».

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

Магазин №4: Магазин очереди

Также известный как суперинтендант

Это хранилище отвечает за организацию всех действий, которые исходят от пользователя, затем переходят на серверную часть (один или несколько раз), а затем возвращаются к пользователю.

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

Например:

  • Организатор встречи создает новое соглашение для голосования, вызывая действие с полем текст (описание соглашения).
  • State (магазин, который мы рассмотрим во второй части этой статьи) уже знает meeting_id, который используется в настоящее время. Таким образом, создателю действия не нужно явно указывать это значение.
  • Мы вызываем на серверной части метод под названием AddAgreement, передавая эти значения, и получаем обратно _id созданного соглашения. .
  • Этот _id позволяет обновить состояние, чтобы это новое соглашение было выбрано на экране.
  • Наконец, мы очищаем состояние (текст нового Соглашения), чтобы оно было доступно для будущих новых соглашений.

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

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

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

Лучшее в этом подходе? У меня есть сотни таких действий, но шаблон все еще остается в силе.

А также определение действия - это просто объект. Взгляните: разве не мило?

Магазин №5: Местный магазин

AKA: Маленькая база данных

Этот магазин - просто оболочка для LocalStorage вашего браузера.

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

Также здесь вы можете полифиллировать локальное хранилище (если вы находитесь в браузере, который не поддерживает localStorage, вы можете использовать куки), а также использовать его в качестве оболочки для AsyncStorage, которые используют React Native.

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

Магазин №6: Магазин часов

Также известен: синхронизатор.

Этот магазин не такой универсальный, как предыдущий, но я сделал его служебным, потому что он используется во многих «модулях приложений» timefic (Dashboard, Planner , Встреча).

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

Предупреждение: этот магазин не является «результатом многих лет разработки» ... Это просто подход, который мне подходит, поэтому используйте его с осторожностью 😊

В двух словах этот магазин:

  • Имеет наблюдаемое поле с именем serverClock.
  • Каждые 1000 миллисекунд он проверяет, есть ли новое значение из serverClockFromStream.
  • Если да, serverClock обновляется этим значением.
  • В противном случае обновляется serverClock, добавляя 1000 мс к предыдущему значению.

Таким образом, из бэкэнда каждые 10 секунд (вы определяете интервал, который лучше всего соответствует вашим потребностям) метка времени отправляется всем подключенным клиентам (поле serverClockFromStream).

Это хранилище импортируется в модули, требующие управления временем, и расширяется за счет вычисляемых полей на основе serverClock и других полей. Например: elapsedTime встречи? Вычтите startDate из serverClock.

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

Магазин №7: Магазин Streams

Также известен: бессерверная связь между клиентами

Наконец, Streams Store - еще один шаблон, который появился вовремя, когда я пытался решить:

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

Конечно, вам нужен компонент React, чтобы подписаться на это событие и творить чудеса с помощью CSS.

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

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