Use lazy reactions in components

This commit is contained in:
Dan Holmsand 2015-09-11 15:06:42 +02:00
parent 679136f5d5
commit b1acdea090
4 changed files with 69 additions and 16 deletions

View File

@ -37,7 +37,10 @@
(dotimes [i (alength a)]
(let [c (aget a i)]
(when (.' c :cljsIsDirty)
(.' c forceUpdate)))))
(let [a (.' c :cljsRatom)]
(if (ratom/-check-clean a)
(.! c :cljsIsDirty false)
(.' c forceUpdate)))))))
(defn run-funs [a]
(dotimes [i (alength a)]
@ -98,7 +101,8 @@
(.! c :cljsRatom
(ratom/make-reaction run
:auto-run #(queue-render c)
:derefed derefed)))
:derefed derefed
:no-cache true)))
res)
(ratom/run rat))))

View File

@ -208,7 +208,8 @@
(deftype Reaction [f ^:mutable state ^:mutable ^number dirtyness
^:mutable watching ^:mutable watches
auto-run on-set on-dispose ^:mutable ^boolean norun?]
auto-run on-set on-dispose ^:mutable ^boolean norun?
^boolean nocache?]
IAtom
IReactiveAtom
@ -261,12 +262,12 @@
(doseq [w watching]
(when (and (instance? Reaction w)
(not (== (.-dirtyness w) clean)))
(-check-clean w)
(when-not (== (.-dirtyness w) clean)
(run w))))
(when-not (-check-clean w)
((or (.-auto-run w) run) w))))
(set! norun? false)
(when (== dirtyness maybe-dirty)
(set! dirtyness clean))))
(set! dirtyness clean)))
(== dirtyness clean))
(-handle-change [this sender oldval newval]
(let [old-dirty dirtyness
@ -278,9 +279,10 @@
(set! dirtyness new-dirty)
(if (some? auto-run)
(when-not norun?
(-check-clean this)
(when-not (== dirtyness clean)
(auto-run this)))
(if-not (identical? auto-run run)
(auto-run this)
(when-not (-check-clean this)
(auto-run this))))
(-notify-watches this state state)))))
(-update-watching [this derefed]
@ -301,7 +303,9 @@
(when (not= derefed watching)
(-update-watching this derefed))
(set! dirtyness clean)
(-notify-watches this oldstate (set! state res))
(when-not nocache?
(set! state res))
(-notify-watches this oldstate state)
res))
IDeref
@ -341,11 +345,12 @@
IHash
(-hash [this] (goog/getUid this)))
(defn make-reaction [f & {:keys [auto-run on-set on-dispose derefed]}]
(defn make-reaction [f & {:keys [auto-run on-set on-dispose derefed no-cache]}]
(let [runner (if (= auto-run true) run auto-run)
dirty (if (nil? derefed) dirty clean)
nocache (if (nil? no-cache) false no-cache)
reaction (Reaction. f nil dirty nil nil
runner on-set on-dispose false)]
runner on-set on-dispose false nocache)]
(when-not (nil? derefed)
(-update-watching reaction derefed))
reaction))

View File

@ -103,7 +103,8 @@
runs (running)
val (r/atom 0)
secval (r/atom 0)
v1 (reaction @val)
v1-ran (atom 0)
v1 (reaction (swap! v1-ran inc) @val)
comp (fn []
(swap! ran inc)
[:div (str "val " @v1 @val @secval)])]
@ -120,13 +121,17 @@
(reset! val 2)
(reset! val 1)
(is (= 1 @ran))
(is (= 1 @v1-ran))
(r/flush)
(is (found-in #"val 1" div))
(is (= 2 @ran) "ran once more")
(is (= 2 @v1-ran))
;; should not be rendered
(reset! val 1)
(is (= 2 @v1-ran))
(r/flush)
(is (= 2 @v1-ran))
(is (found-in #"val 1" div))
(is (= 2 @ran) "did not run")))
(is (= runs (running)))

View File

@ -175,8 +175,8 @@
(is (= @ran 7)))))))
(deftest test-cursor
(let [state (r/atom {:a 0
:b 0})
(let [state (r/atom {:a 1
:b 2})
a-count (r/atom 0)
b-count (r/atom 0)
derefer (fn derefer [cur count]
@ -192,6 +192,45 @@
(is (= @b-count 1))
(swap! state update-in [:a] inc)
(is (= @a-count 1))
(r/flush)
(is (= @a-count 2))
(is (= @b-count 1))
(reset! state @state)
(r/flush)
(is (= @a-count 2))
(is (= @b-count 1))))))
(deftest test-fn-cursor
(let [state (r/atom {:a 1
:b 2})
a-count (r/atom 0)
b-count (r/atom 0)
derefer (fn derefer [cur count]
[:div @cur])
f (fn [[x y]] (swap! y inc) (get-in @state x))
ac (r/cursor f [[:a] a-count])
bc (r/cursor f [[:b] b-count])
comp (fn test-cursor []
[:div
[derefer ac]
[derefer bc]])]
(with-mounted-component [comp]
(fn [c div]
(is (= @a-count 1))
(is (= @b-count 1))
(swap! state update-in [:a] inc)
(is (= @a-count 1))
(is (= @b-count 1))
(r/flush)
(is (= @a-count 2))
(is (= @b-count 2))
(reset! state @state)
(r/flush)
(is (= @a-count 2))
(is (= @b-count 2))))))