5

Om 是 React 的 clojurescript 包装器,据说速度非常快,因为它利用了不变性。我无法理解持久数据结构如何在这里提供帮助。

我所理解的是应用程序状态是一个原子。此状态被传递给返回虚拟 DOM 节点的函数(om 组件),因此创建当前虚拟 DOM 与其先前状态之间差异的“补丁”比直接在实际 DOM 上操作要好得多。

但是持久数据结构在哪里可以提供帮助?

(def app-state (atom {:foo {:counter 0}))
(om/root click-counter app-state {:target ...}) 

例如click-counter,渲染一个按钮,单击该按钮会增加计数器。所以转换函数看起来像这样:

(dom/button #js {:onClick #(om/transact! app [:foo :counter] inc)} 
            (str "clicked " (-> app :foo :counter) " times"))

我不明白这一点:onClick执行 clojurescript 时会创建一个新地图(非常有效),如下所示:

{:foo {:counter 1}}

现在app-state指向新地图。此时 Om 知道状态已更改,因为这只是一次相等检查的问题。

这里的问题是 Om 仍然应该计算整个旧虚拟 DOM 和新虚拟 DOM 之间的差异。它不知道只是改变了计数器。

我的错误在哪里?

4

1 回答 1

4

当应用程序状态存储在像地图这样的持久树结构中时,状态树的哪些部分没有更改并且不需要更新是显而易见的。这是因为对子项的任何更改都会更改父项。使用可变数据结构更改子级不必更改父级。

因此,如果您的状态如下所示:

{:part1 [1 2 3 4]
 :part2 [:a :b]}

然后通过在第 2 部分中添加一些内容来创建一个新状态:

{:part1 [1 2 3 4]
 :part2 [:a :b :c]}

然后比较函数可以查看并看到旧状态和新状态的 :part1 中的值是完全相同的对象,因此不能对任何嵌套状态进行任何更改,因为它是不可变的。

于 2015-06-08T21:31:20.580 回答