当全局变化时,局部试剂原子不会更新

时间:2016-12-23 10:12:53

标签: clojurescript reagent

假设我有一个像这样定义的组件:

(defn test-comp
  [timespan-ratom]
  (let [[timespan-lower timespan-upper] @timespan-ratom]
    (fn []
      [:div.row (str "Testing" timespan-lower timespan-upper)])))

timespan-ratom在实例化test-comp的组件中全局定义,如下所示:

(def timespan-ratom (ratom nil))

它的实例化如下:

[test-comp timespan-ratom]

首次使用timespan-ratom创建test-comp时,“测试”将使用正确的timespan-lowertimespan-upper值打印。但是当重置timespan-ratomreset!)时,test-comp组件中的值不会更新?这是为什么?

当我将功能更改为:

时,它可以正常工作
(defn test-comp
  [timespan-ratom]
    (fn []
      [:div.row (str "Testing" (first @timespan-ratom) (second @timespan-ratom))]))

现在我不能简单地这样做的原因是,在我的实际生产代码中,我有本地ratom,它取决于timespan-ratom的值:

(defn test-comp
  [timespan-ratom]
  (let [[timespan-lower timespan-upper] @timespan-ratom
        selected-time (ratom timespan-upper)]
    (fn []
      ,,,)))

即。 selected-time的初始值应为timespan-upper定义的timespan-ratom值。然后从selected-time组件本地更改test-comp ratom。

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

test-comp

中删除内部函数嵌套
(defn test-comp
  [timespan-ratom]
  (let [[timespan-lower timespan-upper] @timespan-ratom]
    [:div.row (str "Testing" timespan-lower timespan-upper)]))

当你使用没有参数的内部函数时,组件永远不会接收更新的ratom,因此它将永远保持在第一次渲染时从ratom获得的第一个值。此外,您不需要此处的内部函数,因为您没有任何本地状态。

如果你确实有本地状态(某些状态需要在组件的生命周期内被记住),请更新组件,使内部函数与外部函数具有相同的参数,并取消引用内部函数中的原子: / p>

(defn test-comp
  [ratom]
  (let [x "local-state"]
    (fn [ratom]
      (let [v @ratom]
        [:div x v]))))