ClojureScript重新框架订阅解除引用困境

时间:2017-09-12 12:33:44

标签: clojurescript dereference reagent re-frame

以下最佳方法是什么?

外部订阅,早期deref

(defn component [msg]
    [:p msg]))

(let [msg (rf/subscribe [:msg])]
    [component @msg]

外部订阅,迟到deref

(defn component [msg]
    [:p @msg]))

(let [msg (rf/subscribe [:msg])]
    [component msg]

内部订阅,早期deref

(defn component []
   (let [msg @(rf/subscribe [:msg])]
      [:p msg])))

内部订阅,迟到deref

(defn component []
   (let [msg (rf/subscribe [:msg])]
      [:p @msg])))

当我使用外部订阅保持内部组件纯粹时,我最终会得到许多需要通过深度嵌套的常常不相关父级结构的参数。这很容易变得一团糟。

当我订阅内部组件时,它变得不纯净,失去了易测试性。

另外,我想知道早期和晚期解除引用之间是否存在重要差异,除了在测试后者时我必须通过reagent/atom

2 个答案:

答案 0 :(得分:4)

我们的答案一如既往地是“它取决于”,但是......

外部订阅,早期deref 会导致纯粹/可测试的内容。因此,当这对您来说很重要时,这可能是一个不错的选择。但我们并没有太多使用这种风格。

外部订阅,迟到deref 我们已经积极地摆脱了这种风格,因为它产生了我们后来发现难以理解的代码。顺便说一句,如果我们确实传递了ratom / cursors / subscriptions,我们希望在参数名称上放置一个尾随*,以明确它们是引用的东西,而不是值。

内部订阅,早期deref 可能是最常用的,我猜。一段时间后感觉非常自然。也许使用<sub from LIN

内部订阅,迟到deref 这也有效,但我倾向于直接选择上面的变体。总是有一种令人烦恼的担心,你可能忘记在使用时添加@,这可能是一个令人讨厌的bug。

答案 1 :(得分:3)

不知道这是否能解决您的困境,但自从重新排名0.9后,您可以在需要订阅价值的任何地方写@(rf/subscribe [:msg])。订阅被缓存,因此使用相同的路径创建许多订阅不会产生多个订阅。 有关此博客文章的更多信息:https://lambdaisland.com/blog/11-02-2017-re-frame-form-1-subscriptionsthis Re-frame issue