clojurescript原子的哪些更改会导致试剂组件重新渲染?

clojurescript原子的哪些更改会导致试剂组件重新渲染?,clojure,clojurescript,reagent,Clojure,Clojurescript,Reagent,考虑以下试剂成分。它使用一个ref函数,根据span元素的实际大小更新局部状态原子。这样做是为了重新渲染显示其自身大小的组件 (defn show-my-size-comp [] (let [size (r/atom nil)] (fn [] (.log js/console "log!") [:div [:span {:ref (fn [el] (when el (reset! size (get-r

考虑以下试剂成分。它使用一个ref函数,根据span元素的实际大小更新局部状态原子。这样做是为了重新渲染显示其自身大小的组件

(defn show-my-size-comp []
  (let [size (r/atom nil)]
    (fn []
      (.log js/console "log!")
      [:div
       [:span {:ref (fn [el]
                      (when el (reset! size (get-real-size el))))} 
        "Hello, my size is:" ]
       [:span (prn-str @size)]])))
如果
get real size
的实现返回一个向量,则日志消息会不断打印,这意味着组件会一直被不必要地重新渲染。如果它只返回一个数字或字符串,那么日志只会显示两次,这与此场景中的预期相同

这是什么原因?是否可能在内部使用新向量(包含相同的值)更新clojure脚本原子意味着放置另一个JavaScript对象,从而更改原子?然而,设定一个值不会产生可观察到的变化?只是猜测*

无论如何,对于实际用例,在向量中保存跨度的大小肯定会更好。。有没有办法做到这一点

当我试图加强所给出的答案时,我发现了这一点



*因为在JS:
({}==={})//false

中,您可以使用
not=
检查来解决问题:

                (fn [el]
                  (when el
                    (let [s (get-real-size el)]
                      (when (not= s @size)
                        (reset! size s)))))

我不确定向量与其他值不同的原因是什么。

我想我有一个答案,可以解释为什么向量与字符串/数字的行为不同。当
idential?
在新旧值之间返回false时,试剂将试剂原子计数为“已更改”(从而更新依赖于它的组件)。见以下文件中的分目“已更改”:

对于ratoms,相同吗?用于(在ratom内的值上)确定新值是否相对于旧值发生了更改

然而,事实证明,
相同?
对于向量和字符串/整数的行为是不同的。如果启动clj或cljs repl,您将看到:

(identical? 1 1)
;; true 
(identical? "a" "a")
;; true 
(identical? [1] [1])
;; false
(identical? ["a"] ["a"])
;; false
如果您查看
idential?
的作用,您将看到它测试其参数是否是相同的对象。我认为底层的内部数据表示是这样的,在clojure中,“a”始终是与其自身相同的对象,而包含相同值的两个向量彼此不是相同的对象

确认:对于普通原子而不是试剂原子,我们可以看到字符串标识在原子重置时被保留,而向量标识则没有

(def a1 (atom "a"))
(let [aa @a1] (reset! a1 "a") (identical? aa @a1))
;; true
(def a2 (atom ["a"]))
(let [aa @a2] (reset! a2 ["a"]) (identical? aa @a2))
;; false

它的重新命名应该基于它的书写方式。在重置原子时,您将在相同的函数中取消对原子的引用。我总是把这些分开

(defn span-size [size]
  [:span (prn-str @size)])

(defn show-my-size-comp []
  (let [size (r/atom nil)]
    (fn []
      (.log js/console "log!")
      [:div
       [:span {:ref (fn [el]
                      (when el (reset! size (get-real-size el))))}
        "Hello, my size is:"]
       [span-size]])))

我不在可以测试它的设置附近,但尝试将计算的大小记录在
get real size
中。我猜它在不断变化。这是因为每次它得到自己的大小并显示不同的值时,宽度都会改变,所以它会重新渲染,得到一个新的参考,具有不同宽度的新大小……不,我也这么想。当函数为伪函数时也是如此:
(defn get real size[\u0][0])
是这是正确的答案。据我所知,我希望试剂在这种情况下使用相等,但
0.6.0-rc
表现出相同的行为。你认为这是一个错误,还是反应和RATOM之间的故意差异?