嗡,但在JavaScript

我正在成为David Nolen的Om图书馆的粉丝。

我想在我们的团队中构build一个不太大的Web应用程序,但是我不能真正说服我的队友切换到ClojureScript。

有没有一种方法可以使用om中的原则,但在JavaScript中构build应用程序?

我在想:

  1. immutable-js或mori为不可变的数据结构
  2. 用于CSP的js-csp
  3. 只是app-state atom的一个正常的javascript对象
  4. 不可变js的游标
  5. 用于跟踪应用程序状态并在游标上发送通知库

我正在努力与上面的5号。

有没有人冒险进入这个领域或有任何build议? 也许有人已经尝试使用immutable-js构buildreact.js应用程序?

编辑2015年7月 :目前最有前途的基于不变性的框架是Redux ! 看一看! 它不使用Om这样的游标(Om Next不使用游标)。

尽pipe使用下面描述的CQRS原则,但游标并不是真正的可扩展性,但它仍然会在组件中创build过多的样板,难以维护,并且在想要移动现有应用程序时会增加摩擦。

另外,许多开发者不清楚何时使用和不使用游标,而且我看到使用游标的开发人员不应该使用它们,从而使得组件使用简单道具的可重用性更低。

Redux使用connect() ,并清楚地解释何时使用它(容器组件),何时不使用(无状态/可重用组件)。 它解决了将光标向下传递到树上的样板问题,并且没有太多的妥协就performance得很好。

我写了关于在这里不使用connect()缺点

尽pipe不再使用游标,我的答案的大部分仍然有效恕我直言


我在我们的创业内部框架primefaces反应自己做了

JS中的一些替代方法是Morearty , React-cursors , Omniscient或Baobab

那时候还没有一个immutable-js ,我没有进行迁移,仍然使用普通的JS对象(冻结)。

我不认为使用持久的数据结构库真的是必需的,除非你有非常大的列表,你经常修改/复制。 当你注意到性能问题作为优化时,你可以使用这些项目,但似乎并不需要实现Om的概念来利用shouldComponentUpdate 。 有一点可以引起注意的是关于批处理突变的immutable-js部分。 但无论如何,我仍然认为这是优化,并不是使用Om的概念React有非常好的performance的核心先决条件。

你可以在这里find我们的开源代码:

它有一个Clojurescript Atom的概念,它是一个对不可变对象的可交换引用(用DeepFreeze冻结)。 它还具有交易的概念,以防您想要更新primefaces状态的多个部分。 你可以听Atom的变化(交易结束)触发React渲染。

它具有光标的概念,就像在Om(像一个function镜头)一样。 它允许组件能够呈现状态,但也可以轻松修改它。 这对于表单很方便,因为您可以直接链接到游标来进行双向数据绑定:

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

它具有纯粹的渲染的概念,开箱即用 ,比如Om


与Om的区别:

  • 没有本地状态(this.setState(o)禁止)

在Atom-React组件中,不能有本地组件状态。 所有的状态都存储在React之外 。 除非你有现有的Js库的集成需求(你仍然可以使用常规的React类),你可以将所有的状态存储在Atom中(即使是asynchronous/加载值),整个应用程序会从主React组件中恢复。 React只是一个模板引擎,非常高效,可以将JSON状态转换为DOM。 我觉得这非常方便,因为我可以在每个渲染器上logging当前的Atom状态,然后debugging渲染代码非常简单。 由于开箱即用的应用shouldComponentUpdate速度足够快,我甚至可以在用户在文本input上按下新的键盘按键或者用鼠标hoverbutton时重新提交完整的应用程序。 即使在手机上!

  • pipe理国家的意见方式(受CQRS / EventSourcing和Flux的启发)

Atom-React有一种非常自负的方式来pipe理由FluxCQRS启发的状态。 一旦你拥有了React之外的所有状态,并且你有一个有效的方法将这个JSON状态转换为DOM,那么你将发现剩下的难题就是pipe理你的JSON状态。

遇到的一些困难是:

  1. 如何处理asynchronous值
  2. 如何处理需要DOM更改的视觉效果(鼠标hover或焦点为例)
  3. 如何组织你的状态,以便在一个庞大的团队中扩展
  4. 在哪里发起的Ajax请求。

所以我最终得到了受Facebook Flux架构启发的Store的概念。 关键是我真的不喜欢Flux商店实际上依赖于另一个商店的事实,需要通过一个复杂的调度程序协调行动。 而你最终必须了解多个商店的状态才能呈现它们。

在Atom-React中,Store只是Atom所拥有的状态中的“保留的命名空间”。

所以我更喜欢所有的商店,从应用程序中发生的事件stream更新。 每个商店都是独立的,并且不访问其他商店的数据(就像在CQRS架构中,组件接收完全相同的事件,托pipe在不同的机器中,并pipe理他们自己的状态一样)。 这使得维护更容易,因为当你开发一个新的组件时,你只需要了解一个商店的状态。 这不知何故导致数据重复,因为现在多个商店在某些情况下可能需要保留相同的数据(例如,在SPA中,很可能您希望在您的应用程序的许多位置使用当前用户标识)。 但是,如果2个商店将相同的对象置于其状态(来自事件),则实际上不消耗任何额外的数据,因为这仍然是1个对象,在两个不同的商店中被引用两次。

为了理解这个select背后的原因,你可以阅读CQRS领导者Udi Dahan的博客文章,ReUse 的谬论和其他关于自治组件的文章。

所以,商店只是一段代码,它接收事件并在Atom中更新其名称空间的状态。

这将国家pipe理的复杂性转移到另一层。 现在最难的是定义精确的应用程序事件。


请注意,这个项目仍然非常不稳定,没有logging/没有很好的testing。 但是我们已经在这里使用它,取得了巨大的成功 如果你想讨论它或贡献,你可以在IRC上find我: #reactjs Sebastien-L

这就是用这个框架开发SPA的感觉。 每次使用debugging模式渲染时,都有:

  • 将JSON转换为虚拟DOM并将其应用于真实DOM所花费的时间。
  • logging状态帮助您debugging您的应用程序
  • 浪费时间感谢React.addons.Perf
  • pathdiff与以前的状态比较,可以很容易地知道发生了什么变化

检查此屏幕截图:

在这里输入图像描述

这种框架可以带来的一些好处我还没有探索:

  • 你真的有撤销/重做内置(这在我的真正的生产应用程序,而不仅仅是一个TodoMVC)。 然而,恕我直言,恕我直言,许多应用程序中的大多数操作实际上是在服务器上产生副作用,所以并不总是使UI反转到先前的状态,因为之前的状态将会过时

  • 您可以logging状态快照,并将其加载到另一个浏览器中。 CircleCI在此video中已经展示了这一点

  • 您可以以JSON格式录制用户会话的“video”,将它们发送到您的后端服务器进行debugging或重放video。 您可以实时将用户会话stream式传输到其他浏览器以获得用户帮助(或者监视以检查用户的实时UX行为)。 发送状态可能相当昂贵,但可能像Avro格式可以帮助。 或者,如果您的应用程序事件stream是可串行化的,您可以简单地传输这些事件 我已经在框架中轻松地实现了它,它在我的生产应用程序中工作(只是为了好玩,它不会将任何内容传递给后端)

  • 时间旅行debugging可以像ELM一样成为可能

我已经为有兴趣的人制作了“JSONlogging用户会话”function的video 。

你可以有没有另一个React包装和纯Flux的应用程序状态 – 在这里检查https://github.com/steida/este这是我非常完整的React入门套件。;