Ом, но в javascript

Я собираюсь стать поклонником David Nolen библиотеки Om.

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

Есть ли способ использовать принципы, используемые в om, но создавать приложение в JavaScript?

Я думаю что-то вроде:

  • immutable-js или mori для неизменяемых структур данных
  • js-csp для CSP
  • просто обычный объект javascript для атома приложения-состояния
  • immutable-js для курсоров
  • что-то для отслеживания состояния приложения и отправки базы уведомлений на курсоры

Я боюсь с номером 5 выше.

Кто-нибудь рисковал на эту территорию или имел какие-то предложения? Возможно, кто-то попытался создать приложение response.js с помощью immutable-js?

Ответ 1

Изменить июль 2015: в настоящее время наиболее перспективной основой, основанной на неизменности, является Redux! взглянуть! Он не использует курсоры, такие как Om (ни Om Next не использует курсоры).

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

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

Redux использует connect() и четко объясняет, когда его использовать (компоненты контейнера), а когда нет (компоненты без сохранения/повторного использования). Он решает проблему шаблона пропускания курсоров по дереву и выполняет очень много без особых компромиссов.

Я написал о недостатках не использования connect() здесь

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


Я сделал это сам в нашей внутренней структуре запуска atom-react

Некоторые альтернативы в JS Morearty, React- курсоры, Omniscient или Baobab

В то время еще не было immutable-js, и я не выполнял миграцию, все еще используя простые объекты JS (замороженные).

Я не думаю, что использование постоянных структур данных lib действительно требуется, если у вас нет очень больших списков, которые вы часто изменяете/копируете. Вы можете использовать эти проекты, когда заметите проблемы с производительностью в качестве оптимизации, но для реализации концепций Om использовать инструменты shouldComponentUpdate, похоже, не требуется. Интересной может быть одна часть immutable-js о мутациях дозирования. Но в любом случае я все еще думаю, что это оптимизация и не является основным предварительным условием, чтобы иметь очень приличные действия с React, используя концепции Om.

Здесь вы можете найти наш код с открытым исходным кодом:

В нем есть понятие Clojurescript Atom, которое является заменяемой ссылкой на неизменяемый объект (замороженный с помощью DeepFreeze). Он также имеет концепцию транзакции, если вы хотите, чтобы несколько частей состояния были обновлены атомарно. И вы можете прослушивать изменения Atom (конец транзакции), чтобы вызвать рендеринг React.

В нем есть понятие cursor, как в Om (как функциональная линза). Он позволяет компонентам иметь возможность отображать состояние, но также легко изменять его. Это удобно для форм, поскольку вы можете напрямую ссылаться на курсоры для привязки двухсторонней привязки:

<input type="text" valueLink={this.linkCursor(myCursor)}/>

У этого есть концепция чистый рендер, оптимизированный из коробки, как в Om


Различия с Om:

  • Нет локального состояния (this.setState(o) запрещено)

В компонентах Atom-React вы не можете иметь локальное состояние компонента. Все состояние хранится вне React. Если у вас нет требований к интеграции существующих Js-библиотек (вы все равно можете использовать обычные классы React), вы сохраняете все состояние в Atom (даже для значений async/load), и все приложение перераспределяет себя из основного компонента React. Реакция - это просто шаблонный двигатель, очень эффективный, который преобразует состояние JSON в DOM. Я считаю это очень удобным, потому что я могу записывать текущее состояние Atom на каждый рендер, а затем отлаживать код рендеринга так просто. Благодаря явке shouldComponentUpdate это достаточно быстро, что я могу даже перезагрузить полное приложение всякий раз, когда пользователь нажимает новую клавиатуру на текстовом входе или наводит курсор на мышь. Даже на мобильном телефоне!

  • Мнение о способе управления состоянием (вдохновлено CQRS/EventSourcing и Flux)

Atom-React имеет очень упрямый способ управлять состоянием, вдохновленным Flux и CQRS. Когда у вас есть все ваше состояние вне React, и у вас есть эффективный способ превратить это состояние JSON в DOM, вы обнаружите, что оставшаяся трудность заключается в управлении состоянием JSON.

Некоторые из этих трудностей:

  • Как обрабатывать асинхронные значения
  • Как обрабатывать визуальные эффекты, требующие изменений DOM (например, наведение мыши или фокус)
  • Как организовать свое состояние, чтобы оно масштабировалось в большой команде.
  • Где запускать запросы ajax.

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

В Atom-React Store - это просто "зарезервированное пространство имен" внутри хранилища состояния Atom.

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

Чтобы понять причины этого выбора, вы можете прочитать сообщения в блоге о лидере CQRS Уди Дахане, The Fallacy Of ReUse и другие об автономных Компоненты.

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

Это переводит сложность управления состоянием на другой уровень. Теперь сложнее определить с точностью, которая является вашими приложениями.


Обратите внимание, что этот проект по-прежнему очень нестабилен и недокументирован/недостаточно проверен. Но мы уже с большим успехом используем его здесь. Если вы хотите обсудить это или внести свой вклад, вы можете связаться со мной в IRC: Sebastien-L в #reactjs.

Это то, что он чувствует, чтобы создать SPA с этой структурой. Каждый раз, когда он отображается, в режиме отладки у вас есть:

  • Время, необходимое для преобразования JSON в Virtual DOM и применения его к реальному DOM.
  • Зарегистрированное состояние, чтобы помочь вам отладить ваше приложение
  • Потерянное время благодаря React.addons.Perf
  • Путь diff по сравнению с предыдущим состоянием, чтобы легко узнать, что изменилось

Установите этот снимок экрана:

enter image description here

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

  • У вас действительно есть отменить/переделать (это получилось из коробки в моем реальном рабочем приложении, а не только в TodoMVC). Однако IMHO большинство действий во многих приложениях на самом деле создает побочные эффекты на сервере, поэтому он не всегда позволяет переключить пользовательский интерфейс на предыдущее состояние, поскольку предыдущее состояние было бы устаревшим.

  • Вы можете записывать снимки состояния и загружать их в другой браузер. CircleCI показал это в действии на это видео

  • Вы можете записывать "видео" пользовательских сеансов в формате JSON, отправлять их на ваш серверный сервер для отладки или воспроизведения видео. Вы можете транслировать сеанс пользователя в другой браузер для помощи пользователям (или отслеживать, чтобы проверить поведение UX в реальном времени ваших пользователей). Отправляющие состояния могут быть довольно дорогими, но, вероятно, такие форматы, как Avro, могут помочь. Или, если поток событий вашего приложения сериализуется, вы можете просто передать эти события. Я уже реализовал это легко в рамках, и он работает в моем рабочем приложении (просто для удовольствия, он еще ничего не передает серверу)

  • Отладка во время путешествия возможна, как в ELM

Я сделал видео с функцией "запись пользовательской сессии в JSON" для тех, кого это интересует.

Ответ 2

У вас может быть Om, как состояние приложения, без еще одной оболочки React и с чистым Flux - проверьте его здесь https://github.com/steida/este Это мой очень полный Реакт стартовый комплект.