Ant*_*ald 2 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-real-size el))))}
"Hello, my size is:" ]
[:span (prn-str @size)]])))
Run Code Online (Sandbox Code Playgroud)
如果 的实现get-real-size返回一个向量,则日志消息会不断打印,这意味着组件一直在不必要地重新渲染。如果它只返回一个数字或一个字符串,则日志只会出现两次 - 正如本场景中所预期的那样。
这是什么原因?是否可能在内部使用新向量(尽管包含相同的值)更新 clojure 脚本原子意味着将另一个 JavaScript 对象放在那里,从而更改原子?而放置一个值不会产生可观察到的变化?只是猜测...*
无论如何 - 对于实际用例,将跨度的大小保存在向量中肯定会更好.. 有没有办法实现这一点?
* 因为在 JS 中: ({} === {}) // false
我想我有一个答案,为什么矢量的行为与字符串/数字不同。当identical?在旧值和新值之间返回 false时,试剂将试剂原子计数为“已更改”(从而更新依赖于它的组件)。看到小标题“改变了吗?” 在本教程中:
对于ratom,相同吗?用于(在随机数内的值上)确定新值是否相对于旧值发生了变化。
然而,事实证明identical?对于向量和字符串/整数的行为不同。如果您启动 clj 或 cljs repl,您将看到:
(identical? 1 1)
;; true
(identical? "a" "a")
;; true
(identical? [1] [1])
;; false
(identical? ["a"] ["a"])
;; false
Run Code Online (Sandbox Code Playgroud)
如果你看看这里identical?做了什么,你会看到它测试它的参数是否是同一个对象。我认为底层的内部数据表示是这样的,在 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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
540 次 |
| 最近记录: |