#clojurescript #reagent
#clojurescript #реагент
Вопрос:
Я использую несколько атомов в карте, называемой app-state, и пока она работает довольно хорошо с архитектурной точки зрения. Состояние, распределенное по этим атомам, нормализуется, отражая, как оно хранится в datomic, и, конечно, то, с чем инициализируется клиент, является определенным подмножеством того, что находится в datomic. Это я готовлю способ опробовать datascript (именно это дало мне понять, почему состояние клиента намного лучше полностью нормализовано, даже если не используется datascript).
На данный момент у меня есть вопрос. Мы все знаем, что некоторое состояние в reagent является отражением того, что находится в базе данных сервера (обычно), но в reagent также есть состояние, касающееся исключительно текущего состояния пользовательского интерфейса. Это состояние исчезнет при повторной загрузке страницы, и (как правило) нет необходимости хранить его на сервере.
Итак, я смотрю на свой список атомов и понимаю, что у меня есть несколько атомов, которые содержат карты, подобные записям базы данных, т. Е. Они содержат точные отражения объектов datomic (которые поступают транзитом), и это здорово.
Но теперь я замечаю, что мне также нужно некоторое состояние пользовательского интерфейса для каждого объекта datomic. Итак, возникает вопрос, следует ли (мне это кажется неправильным) добавить некоторые ключи к тому, что пришло из datomic, состояния пользовательского интерфейса, которое не имеет отношения к datomic, но которое нужно клиенту (т. Е. Выгрузить его на ту же вложенную карту).). Это вполне возможно, но кажется неправильным, и поэтому предполагает …. (на данный момент это моя идея), как насчет параллельного атома для каждого «объекта», например @<entity-name>-ui
, содержащего карту (или даже вектор карт, если несколько объектов), с набором ключей длясостояние пользовательского интерфейса.
Это кажется улучшением по сравнению с тем, что я получил по умолчанию на данный момент, который является отдельным атомом для каждой части состояния пользовательского интерфейса (до сих пор я избегал локального состояния компонента). (В настоящее время пользовательский интерфейс содержит состояние пользовательского интерфейса только для одной записи за раз, поэтому эти атомы пользовательского интерфейса должны относиться только к одному текущему объекту).
Но если, скажем, я создал параллельный атом (чтобы избежать смешивания эфемерного пользовательского интерфейса и состояния сервера), то состояние пользовательского интерфейса, возможно, могло бы быть управляемо расширено глубже. Мы могли бы хранить, скажем, состояние пользовательского интерфейса для каждого объекта, чтобы переключение текущего объекта туда и обратно запоминало состояние пользовательского интерфейса.
Поскольку это переполнение стека, я должен задать конкретный вопрос, а не просто обсудить, итак: учитывая то, что я описал, каковы некоторые разумные архитектурные варианты в этом случае для сохранения состояния в реагенте?
Комментарии:
1. Это довольно открытый конец. Для подобных тем, которые больше обсуждаются, я бы предложил clojure reddit (reddit.com/r/clojure ) или клоджурийцы расслабляются.
Ответ №1:
Если вы уже храните состояние своего приложения в нескольких компонентно-независимых атомах реагента — вы можете проверить https://github.com/day8/re-frame это широко распространенная система, основанная на реагентах, специально для вашего случая. По сути, он хранит все состояние приложения в атоме реагента, но имеет хорошо развитую инфраструктуру для поддержки скоординированного хранения и обновлений. У них есть блестящая документация с отличным высокоуровневым объяснением идеи. Что касается вашего первоначального вопроса о разделении состояний сервера и пользовательского интерфейса — я думаю, вам определенно следует пойти этим путем. Это даст вам лучший способ разделения проблем и даст вам более простой способ обновлять данные сервера / пользовательского интерфейса отдельно. Этого очень легко достичь re-frame
, сохранив обе части состояния под отдельными ключами верхнего уровня в базе данных приложений re-frame. Например.
{:server {:entity-name ...}
:ui {:entity-name ...}}
а затем создайте подходящие подписки (см. Документы re-frame) для его извлечения.