Clojurescript Om中应用程序状态和组件本地状态之间的区别是什么?

Clojurescript Om中应用程序状态和组件本地状态之间的区别是什么?,clojurescript,om,Clojurescript,Om,我已经阅读了David Nolen的基本Om教程,但对于应用程序状态和组件本地状态之间的区别,我仍然有点困惑。当提到游标时,它是指这些游标中的一个还是两个呢?据我所知: 应用程序状态是组件树中的所有组件都可以通过游标访问的“全局”状态。这是应用程序所处的状态,基本上是Om呈现的状态。因此,例如,如果您正在编写聊天程序,应用程序状态将包含对话中的用户列表和所有已发送的消息,或者其他内容 组件本地状态是单个组件的本地状态,在该组件外部无法看到。通过将{:init state}传递给build,或者通

我已经阅读了David Nolen的基本Om教程,但对于应用程序状态和组件本地状态之间的区别,我仍然有点困惑。当提到游标时,它是指这些游标中的一个还是两个呢?

据我所知:

应用程序状态是组件树中的所有组件都可以通过游标访问的“全局”状态。这是应用程序所处的状态,基本上是Om呈现的状态。因此,例如,如果您正在编写聊天程序,应用程序状态将包含对话中的用户列表和所有已发送的消息,或者其他内容

组件本地状态是单个组件的本地状态,在该组件外部无法看到。通过将{:init state}传递给build,或者通过实现IInitState并从init state返回一个映射,或者通过两者(在本例中,它们结合在一起)来设置它。David Nolen建议,本地状态应仅用于瞬态,例如,如果鼠标当前在拖放组件中按下,则所有其他状态应为应用程序状态。也就是说,如果您有一个tab小部件,当前选定的tab应该设置为应用程序状态(而不是本地状态!),但是如果该选项卡被拖动到一个新位置,则当前位置和鼠标状态将(暂时-直到拖动操作完成)存储在组件本地状态。像core.async通道这样的东西也可以存储在本地状态(尽管我也在共享状态和其他数据中存储了它们(并且看到其他人也这样做了)——请参阅下文以了解这两个方面的详细信息)

游标只应用于应用程序状态,就像进入应用程序状态的窗口一样,因此树下的组件只能访问它们实际需要访问的数据

应用程序状态总是通过游标(教程中的应用程序)访问,修改应用程序状态是通过游标完成的-om/更新!和om/transact!将光标作为它们的第一个参数。您还可以直接用reset设置应用程序状态atom!交换!,但David建议不要这样做,因为这样做会使您失去Om的一些更高级的功能(例如收到更改增量的通知)

本地状态可以通过IRenderState接收,也可以通过om/get state直接访问。您可以使用om/set state设置本地状态!和om/upate状态!。这三种方法都采用组件支持对象(教程中的所有者)

Om中还有第三种状态:共享状态。共享状态使用{:Shared…}选项传递给om/root,并且可以使用om/get Shared从该根目录下树中的任何组件进行访问。此状态与应用程序状态之间的区别在于,应用程序状态通过游标路径缩小,也就是说,子组件可能无法访问整个应用程序状态,而共享状态始终是可访问的。另外,修改应用程序状态会导致组件重新呈现,而共享状态不会触发呈现


另一方面,实际上还有第四种类型-您可以使用{:opts…}选项通过构建将额外的数据传递给组件。这是存在于Om/react生命周期之外的数据—也就是说,您可以从组件访问它的不可变数据,但组件不以任何方式管理它。这似乎对配置数据最有用。

谢谢您的精彩回答!尽管这可能令人困惑,但实际上还有第五种类型:可以称之为派生/辅助状态的东西。
om/build
函数有一个
:fn
选项,可以转换组件读取的光标数据。感谢您提出这个问题!