我所理解的是应用状态是一个原子。此状态被传递给返回虚拟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之间的差异。它不知道只是计数器被改变了。
我的错误在哪里?
答案 0 :(得分:4)
当app状态存储在像地图这样的持久树结构中时,它立即明显地显示状态树的哪些部分没有改变,并且不会需要更新。这是因为对子项的任何更改都会更改父项。随着可变数据结构的变化,孩子们不必改变父母。
所以如果你的州看起来像这样:
{:part1 [1 2 3 4]
:part2 [:a :b]}
并通过在第2部分中添加内容来创建新状态:
{:part1 [1 2 3 4]
:part2 [:a :b :c]}
然后比较函数可以查看并看到旧状态和新状态