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

Local reagent atom won't update when global ratom change

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

(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 "Testing" 时将打印出正确的 timespan-lowertimespan-upper 值。但是当 timespan-ratom 被重置 (reset!) 时 test-comp 组件中的值没有更新?这是为什么?

当我将函数更改为这个时它起作用了:

(defn test-comp
  [timespan-ratom]
    (fn []
      [:div.row (str "Testing" (first @timespan-ratom) (second @timespan-ratom))]))

现在我不能简单地这样做的原因是在我的实际生产代码中我有依赖于 timespan-ratom:

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

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

我该如何解决这个问题?

test-comp移除内部函数嵌套:

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

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

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

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